Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending controller in ExtJS 4 MVC application

I building my ExtJS 4 application following the MVC structure. I want to make an extendable grid MyGrid with some functionality that I can reuse several times. Therefore, I guess, it should have its own controller which is also extended, so that the functionality is inherited. How is this properly done?

In the code below I illustrate how I extend the controller MyGrid with MyExtendedGrid. I realize that I'm overriding the init function in the MyGrid controller, so that it is never called. Is the problem simply solved by calling the "super" init in MyGrid from MyExtendedGrid init, or merge the control objects? Is that the proper way to do this in the MVC spirit? If so, how?

controller/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()
            }
        });
    }
});

view/grids/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);
    }
});

view/grids/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);
    }
});
like image 962
Louis Avatar asked Mar 02 '12 17:03

Louis


1 Answers

It's actually a bit trickier...

Here is what we did in our application (we have exact same situation - some kind of base controller, that is reused in many different places)

  1. Keep init function in base controller.

  2. Define common base method in this base controller (like gridRendered - where you need to do something for all controllers all the time).

  3. Subscribe to the events in all child controllers but subscribe events using methods of base controller. It won't work otherwise - base controller doesn't have proper refs to properly subscribed to events.

I can post couple source snippets, but I think it's pretty straightforward.

like image 147
sha Avatar answered Oct 22 '22 13:10

sha