View Full Version : MVC: Controller reference from Grid's Action Cell handler.

I'm Dennis
22 Nov 2011, 7:01 AM
How to get Controller's object reference from grid's actioncolumn's cell handler?

I have an application and have method defined in controller

Ext.define('myApp.controller.Users', {
extend: 'Ext.app.Controller',
myHandler: function(record) {
// some cool code here

I also add an actioncolumn like this in my grid:

... some code for Grid ...
columns: [
... other columns ...
xtype: 'actioncolumn',
items: [
icon: 'edit_item.png',
handler: function(grid, rowIndex, colIndex) { // trying to handle click
var record = grid.getStore().getAt(rowIndex);
// Now I need a reference to my Users controller of application!
myApp.controller.Users.myHandler(record) // does not work

Code at red line does not work, because myApp var is not initialized properly yet while this piece of code is running.

I need a proper way to reference Controller object (or Application object) at this piece of column-configuration code.

22 Nov 2011, 7:49 AM
imho this is not the best approach.

the MVC is not meant to have controllers with a collection of methods and views with handlers directly calling the controller.

the idea is, that the controller listens for view events itself and calls its own methods then.

take a look at ComponentQuery to see how to identify view elements and events to listen to:

and also into the controller definitions:


Ext.define('MyApp.controller.Users', {
extend: 'Ext.app.Controller',

init: function() {
'viewport > panel': {
render: this.onPanelRendered

onPanelRendered: function() {
console.log('The panel was rendered');

I'm Dennis
23 Nov 2011, 3:27 AM
Thanks, tobiu

But in my case it's probably better to fire some custom event during click on action columns action button like this:

handler: function(grid, rowIndex, colIndex) {
var record = grid.getStore().getAt(rowIndex);
this.fireEvent('myCustomEventMeaningClickOnAction', this, record);

And after that i can listen to this myCustomEventMeaningClickOnAction in controller ...
Is it ok from designing app point of view?

23 Nov 2011, 4:14 AM
hi dennis,

action columns have the method:

* @private
* Process and refire events routed from the GridView's processEvent method.
* Also fires any configured click handlers. By default, cancels the mousedown event to prevent selection.
* Returns the event handler's status to allow canceling of GridView's bubbling process.
processEvent : function(type, view, cell, recordIndex, cellIndex, e){
var me = this,
match = e.getTarget().className.match(me.actionIdRe),
item, fn;

if (match) {
item = me.items[parseInt(match[1], 10)];
if (item) {
if (type == 'click') {
fn = item.handler || me.handler;
if (fn && !item.disabled) {
fn.call(item.scope || me.scope || me, view, recordIndex, cellIndex, item, e);
} else if (type == 'mousedown' && item.stopSelection !== false) {
return false;
return me.callParent(arguments);

so they listen to click events already (fetching it from the gridView to be more precise). i would try to listen to this event directly. if that is not possible in a way you need it, it would possibly override this method to fire the event manually there.

well, your approach also gets the job done, so i see no problem in keeping it this way. if you have many action columns in different modules, you might be feeling more comfortable with the "generic" override, since it saves some boiler plate code in that case.

it might be worth a try to add a feature request for the event "actionClicked".

I'm Dennis
23 Nov 2011, 4:20 AM
well ... my main problem is getting those action columns objects from controller's control method (via Ext.ComponentQuery) using some approach like assigning some CSS class to them and after that trying to work with classnames.

For now it's easier for me to fire custom events in all my views/components objects and have just one listener in Controller object. But approach of having list of objects to be listened in Controller works too ...

Thanks again