9

MVC 構造に従って ExtJS 4 アプリケーションを構築しています。何度か再利用できるいくつかの機能を備えた拡張可能なグリッド MyGrid を作成したいと考えています。したがって、機能が継承されるように、拡張された独自のコントローラーが必要だと思います。これはどのように適切に行われますか?

以下のコードでは、コントローラー MyGrid を MyExtendedGrid で拡張する方法を示しています。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
                }
            }
        });
    }
});

controller/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. ベースコントローラでinit関数を保持します。

  2. このベースコントローラーで共通ベースメソッドを定義します(gridRenderedのように-すべてのコントローラーに対して常に何かを行う必要があります)。

  3. すべての子コントローラーのイベントをサブスクライブしますが、ベースコントローラーのメソッドを使用してイベントをサブスクライブします。それ以外の場合は機能しません-ベースコントローラーには、イベントを適切にサブスクライブするための適切な参照がありません。

いくつかのソーススニペットを投稿できますが、それはかなり簡単だと思います。

于 2012-03-02T20:51:49.667 に答える
1

OK、いくつか考えた後、次の解決策を決定しました。これには、mygrid が myextendedgrid について知る必要がないという利点があります。

質問のようにグリッドビューを拡張します。

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'Ext.app.Controller'MyGrid コントローラーの関数または変数を使用したい場合を除き、MyGrid クラスから (むしろ から) コントローラーを拡張しません。すべてのコントローラーは、次を使用して app.js から開始されます。

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

グリッドで行が選択されたときにグリッドを取得するために、以下のように選択モデルにグリッドを保存しました。

controller/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 に答える