Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Perform Controller Inheritance in ExtJS 4?

I'm looking to write a fairly complex application that would involve having several "base" items (a base form, a base grid, etc.) that other items would inherit from in order to follow DRY. These base items would have common events that all inheriting items would fire. Since this is the case, I'll need some kind of base controller that will listen for these items events.

What's the base way to set up a controller to easily be inherited / extended?

like image 308
Levi Hackwith Avatar asked Mar 09 '12 02:03

Levi Hackwith


1 Answers

This is exactly what we're doing in our project. Here are couple samples for grid/controller combo:

BaseGrid:

Ext.define('BaseGrid', {
  extend: 'Ext.grid.Panel',

  initComponent: function() {
    var me = this;
    // create common stuff

    me.on('itemcontextmenu', me.showContextMenu, me); 
    me.callParent(arguments); 
  },

  showContextMenu: function(view, rec, node, index, e) {
    var me = this;

    if (me.contextMenu === undefined)
      return;

    e.stopEvent();
    me.contextMenu.showAt(e.getXY());
  }

});

BaseController:

Ext.define('BaseController', {
  extend: 'Ext.app.Controller',

    init: function() {
      // put some common stuff


      this.callParent(arguments);
    },

    gridRendered: function() {
    // common function to do after grid rendered
       var me = this,
           grid = me.getGrid(); // note that base controller doesn't have ref for Grid but we still using it !!

       gr.contextMenu = me.createContextMenu();
    },

    createContextMenu: function() {
       return ...  // create context menu common for all grids with common handlers
    },

});

ChildGrid:

Ext.define('ChildGrid', {
  extend: 'BaseGrid',
  alias: 'widget.child'
...

});

ChildController:

Ext.define('ChildController', {
  extend: 'BaseController',

  refs: [
    { ref: 'grid', selector: 'child gridpanel' } // now basecontroller will have something when called getGrid()!! 
  ],

  init: function() {
     var me = this;
     me.control({
        'child gridpanel': {
            afterrender: me.gridRendered, // subscribing to the event - but using method defined in BaseController
            scope: me
         }
     });

     me.callParent(arguments);

  }, 
});

Hope these couple samples help. The basic ideas are these:

  • You put as much code as possible into base controls and base controllers
  • You use refs functions (getGrid() etc) in base controllers
  • Don't forget to create these refs in all child controllers
  • Link several key events to the base controller handlers in the child controllers.
like image 82
sha Avatar answered Oct 27 '22 20:10

sha