2011-10-04 34 views
8

假設我有一個主控制器,那麼我的應用程序爲每個「模塊」都有一個控制器。這個主控制器包含視口,然後是一個標題(帶有菜單)+一個「居中」容器,它在開始處是空的。使用多個控制器與ExtJS 4 MVC

菜單中的單擊將更改當前模塊/控制器,並且特定視圖(屬於此控制器)將顯示在居中容器中。

我認爲這是一個非常簡單的場景,但奇怪的是我沒有找到合適的方式來做到這一點。有任何想法嗎?非常感謝!

回答

9

這是我做的事:我有一個工具欄在頂部,左側導航和中心位置是工作區(基本上是一個選項卡面板),就像你提到的。讓我們每一部分FO的應用和explain.First,這裏是我的視口看起來怎麼樣:

Ext.define('App.view.Viewport',{ 
    extend: 'Ext.container.Viewport', 
    layout: 'border', 
    requires: [ 
     'App.view.menu.NavigationPane', 
     'App.view.CenterPane',   
     'App.view.menu.Toolbar' 
    ], 
    initComponent: function() { 
     Ext.apply(this, { 
      items: [{ 
       region: 'north', 
       xtype: 'panel',     
       height: 24,          
       tbar: Ext.create('App.view.menu.Toolbar')          
      },{ 
       title: 'Navigation Pane', 
       region: 'west', 
       width: 200, 
       layout: 'fit', 
       collapsible: true, 
       collapsed: true, 
       items: Ext.create('App.view.menu.NavigationPane')          
      },{ 
       region: 'center',            
       xtype: 'centerpane'          
      }]  
     }); 

     this.callParent(arguments); 
    } 
}); 

你可以看到,我有一個工具欄(App.view.menu.Toolbar)與菜單左側導航( App.view.menu.NavigationPane)。這兩個組件構成了我的主菜單或其他模塊的網關。用戶選擇菜單項,並將相應的模塊視圖(如表單,網格,圖表等)加載到「中間層」中。中間層只是Ext.tab.Panel的派生類。

就像你說的,我有一個主控制器來處理來自工具欄和導航窗格的所有請求。它只處理工具欄和導航窗格的點擊操作。這是我的AppController:

Ext.define('CRM.controller.AppController',{ 
    extend: 'Ext.app.Controller',  
    init: function() { 

     this.control({ 

      'apptoolbar button[action="actionA"]' : { 
        click : function(butt,evt) { 
          this.application.getController('Controller1').displayList(); 
        } 
      }, 
      . 
      . // Add all your toolbar actions & navigation pane's actions... 
      .   
      'apptoolbar button[action="actionB"]' : { 
        click : function(butt,evt) { 
          this.application.getController('Controller2').NewRequest(); 
        } 
      } 
     });  
    } 
}); 

看看我的按鈕的處理程序之一。我通過「應用」屬性來獲取控制器的保持:

this.application.getController('Controller2').NewRequest(); 

隨着getController方法的幫助下,我得到了控制器的實例,然後調用我的控制器內的任何方法。現在讓我們看看我的模塊控制器的骨架:

Ext.define('CRM.controller.Controller2',{ 
    extend: 'Ext.app.Controller',  
    refs: [   
     {ref:'cp',selector: 'centerpane'}, // reference to the center pane 
     // other references for the controller 
    ], 
    views: ['c2.CreateForm','c2.EditForm','c2.SearchForm','c2.SearchForm'], 
    init: function() { 

     this.control({ 

      'newform button[action="save"]' : { 
       // Do save action for new item 
      }, 
      'editform button[action="save"]' : { 
       // update the record... 
      }, 
      'c2gridx click' : { 
       // oh! an item was click in grid view 
      } 
     });  
    }, 
    NewRequest: function() { 
     var view = Ext.widget('newform'); 
     var cp = this.getCp();  // Get hold of the center pane... 
     cp.add(view); 
     cp.setActiveTab(view); 
    }, 
    displayList: function() { 
     // Create grid view and display... 
    } 
}); 

我模塊的控制器只與該模塊(模塊的網格,表格等)的行動。這應該可以幫助你開始正確的方向滾動。

+0

謝謝你的美好的解釋,但對我來說還是一個問題。請檢查我給以前答案(techknowfreak)的評論。 – TigrouMeow

+0

對不起,我沒有得到你。在哪裏知道父控制器的所謂的子控制器?你能詳細說明嗎?在上面的代碼中,沒有從模塊控制器到主控制器的交互。對?或者我理解你錯了。:) –

+1

對不起,子控制器不知道_parent view_('centerpane'here)。我希望模塊(一堆控制器+視圖)能夠獨立。 – TigrouMeow

1

在主控制器菜單

Ext.define('MyAPP.controller.MainController',{ 
... 
    init:function() 
    { 
    this.control({ 
    'menulink': 
    { 
     click:this.populateCenterPanel 
    } 
    }); 
    }, 
    populateCenterPanel:function() 
    { 
    this.getController('ChildController'); 
    } 
}); 

的Click事件處理程序在發射功能添加子控制器添加監聽器控制器添加事件這樣的 - 對於動態嵌入觀點

Ext.application({ 
... 
    launch:function(){ 
    this.controllers.addListener('add',this.newControllerAdded,this); 
    }, 

    newControllerAdded:function(idx, ctrlr, token){ 
    ctrlr.init(); 
    } 
}); 

現在把代碼在ChildController的init方法的視口中。

Ext.define('MyAPP.controller.ChildController',{ 
... 
    refs: [ 
    {ref:'displayPanel',selector:'panel[itemId=EmbedHere]'} 
    ] 
    init:function(){ 
    var panel=this.getDisplayPanel(); 
    panel.removeAll(); 
    panel.add({ 
     xtype:'mycustomview', 
     flex:1, 
     autoHeight:true, 
     ... 
    }); 
    } 
}); 

HTH :)

+0

這就是我的想法,問題是我想避免孩子控制器知道它的父母是什麼。這有點像一個嬰兒在出生前選擇他的父母,對吧? :p – TigrouMeow

+0

然後使用應用程序事件...讓主控制器在單擊菜單並由子控制器處理時觸發應用程序事件。 – techknowfreak

+1

這就是我現在所做的,我將'主容器'的id傳遞給控制器​​,以便我可以正確使用'this.control'和'refs'。儘管如此,我認爲這是很多小技巧,我很樂意通過框架動態管理所有這些: – TigrouMeow

相關問題