9

我按照 MVC 结构构建我的 ExtJS 4 应用程序。我想制作一个可扩展的网格 MyGrid,它具有一些我可以重复使用多次的功能。因此,我想,它应该有自己的控制器,它也被扩展,以便继承功能。这是如何正确完成的?

在下面的代码中,我说明了如何使用 MyExtendedGrid 扩展控制器 MyGrid。我意识到我正在重写 MyGrid 控制器中的init函数,因此它永远不会被调用。通过从 MyExtendedGrid init调用 MyGrid 中的“超级” init或合并控件对象是否可以简单地解决问题?这是在 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);
    }
});
4

2 回答 2

1

其实有点棘手...

这是我们在应用程序中所做的(我们有完全相同的情况 - 某种基本控制器,在许多不同的地方重用)

  1. 在基本控制器中保留初始化功能。

  2. 在此基本控制器中定义通用基本方法(如 gridRendered - 您需要一直为所有控制器执行某些操作)。

  3. 订阅所有子控制器中的事件,但使用基本控制器的方法订阅事件。否则它将无法工作 - 基本控制器没有适当的参考来正确订阅事件。

我可以发布几个源代码片段,但我认为这很简单。

于 2012-03-02T20:51:49.667 回答
1

好的,经过一番思考,我决定采用以下解决方案,它的优点是 mygrid 不需要了解 myextendedgrid。

我在问题中扩展了我的gridview。

我为基础网格提供了自己的控制器来执行通用功能,例如deleteButton.setDisable(false)在网格中选择某些内容时。

接下来,我提醒自己使用refs:[(例如 with 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 控制器的函数或变量。所有控制器都从 app.js 使用:

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

为了在网格中选择行时获取网格,我将网格存储在选择模型中,如下所示:

在控制器/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
        }
...
于 2012-03-08T15:21:48.920 回答