2012-03-02 78 views
9

我構建了遵循MVC結構的ExtJS 4應用程序。我想用一些可以重複使用的功能來創建可擴展的網格MyGrid。因此,我想,它應該有它自己的控制器,它也被擴展了,所以這個功能是被繼承的。這是如何正確完成的?在ExtJS 4 MVC應用程序中擴展控制器

在下面的代碼中,我演示瞭如何使用MyExtendedGrid擴展控制器MyGrid。我意識到我在覆蓋MyGrid控制器中的init函數,因此它永遠不會被調用。是通過調用MyExtendedGrid中的「超級」初始化從MyExtendedGrid 初始化或合併控制對象簡單地解決的問題?這是MVC精神中做到這一點的正確方法嗎?如果是這樣,怎麼樣?

控制器/ MyGrid.js:

Ext.define('App.controller.MyGrid', { 
    extend: 'Ext.app.Controller', 
    refs: [ 
     { 
      ref: 'myGridView', 
      selector: 'mygrid' 
     } 
    ], 
    init: function() { 
     var me=this; 
     me.control({ 
      'mygrid textfield[name=searchField]': { 
       change: function() { 
        var view = me.getMyGridView(); 
        // Do something with view 
       } 
      } 
     }); 
    } 
}); 

控制器/ MyExtendedGrid.js:

Ext.define('App.controller.MyExtendedGrid', { 
    extend: 'App.controller.MyGrid', 
    views: [ 
     'grids.MyExtendedGrid'], 
    refs: [ 
     { 
      ref: 'myExtendedGridView', 
      selector: 'myextendedgrid' 
     } 
    ], 
    init: function() { 
     var me=this; 
     me.control({ 
      'myextendedgrid': { 
       // Some control code 
       // Using getMyExtendedGridView() 
      } 
     }); 
    } 
}); 

視圖/網格/ MyGrid.js:

Ext.define('App.view.grids.MyGrid', { 
    extend: 'Ext.grid.Panel', 
    alias : 'widget.mygrid', 
    requires: [ 
    ], 
    store: '', // Not defined here 
    columns: [ ], // Not defined here 

    initComponent: function() { 
     var me = this; 
     me.tbar = [ 
      'Search', 
      { 
       xtype: 'textfield', 
       name: 'searchField', 
       hideLabel: true, 
       width: 150 
      } 
     ]; 
     me.callParent(arguments); 
    } 
}); 

視圖/網格/ MyExtendedGrid .js:

Ext.define('App.view.grids.MyExtendedGrid', { 
    extend: 'App.view.grids.MyGrid', 
    alias : 'widget.myextendedgrid', 
    store: 'MyStore', 
    columns: [ 
     // ... 
    ], 

    initComponent: function() { 
     var me = this; 
     me.bbar = [ 
      //... 
     ]; 
     me.callParent(arguments); 
    } 
}); 

回答

2

好的,經過一番思考後,我決定採用以下解決方案,它具有mygrid不需要了解myextendedgrid的優勢。

我在問題中擴展了我的gridview。

我給基礎網格自己的控制器做了常用的功能,例如deleteButton.setDisable(false)當網格中選擇了某些東西時。

接下來,我提醒自己,使用refs:[(例如selector: 'mygrid')會模糊地指向基類的任何擴展實例的兩個實例。當使用me.control({我,而不是通過使用up激活元素遍歷得到相關的網格:

me.control({ 
    'mygrid textfield[name=searchField]': { 
     change: function(searchfield) { 
      var grid=searchfield.up('mygrid'); // (mygrid or myextendedgrid!) 
      // Do something with view 
     } 
    } 
... 

擴展網格我給自己的控制器,在這裏我可以用refs。我沒有從MyGrid類(而是從'Ext.app.Controller')擴展控制器,除非我想使用MyGrid控制器中的函數或變量。

Ext.application({ 
    controllers: [ 
     'MyGrid' 
     'MyExtendedGrid', 
    ], 
... 

爲了獲得當行在網格選擇網格,我存儲在如下文所述選擇模型中的網格::所有的控制器都從app.js使用開始

在控制器/ MyGrid.js:

me.control({ 
    'mygrid': { 
     afterrender: function(grid) { 
      var selModel=grid.getSelectionModel(); 
      selModel.myGrid=grid; 
     }, 
     selectionchange: function(selModel, selected, eOpts) { 
      var grid=selModel.theLookupGrid; 
      // Do something with view 
     } 
... 
1

它實際上有點棘手...

下面是我們在我們的應用程序沒有(我們有完全相同的情況 - 某種基地控制器,即在許多不同的地方重複使用)

  1. 保持基礎控制器的初始化功能。

  2. 在此基礎控制器中定義通用基礎方法(如gridRendered - 您需要爲所有控制器始終執行某些操作)。

  3. 訂閱所有子控制器中的事件,但使用基本控制器的方法訂閱事件。否則它將無法工作 - 基礎控制器沒有適當的參考來正確訂閱事件。

我可以發佈幾個源代碼片段,但我認爲它非常簡單。

+0

謝謝你給了我一些啓發.. – Louis 2012-03-08 15:22:27

+0

@sha我真的喜歡它,如果你發佈的代碼片段或兩個。 – 2012-03-08 21:16:05

+0

@LeviHackwith:沒問題。讓我們在單獨的問題中做這個,所以我們不要混淆這個。想發佈新的問題? – sha 2012-03-08 21:32:23