Search code examples
extjs4extjs-mvc

How to perform View-Controller separation when using an "actioncolumn" (Ext.grid.column.Action)


In ExtJS 4, I have a grid that contains an action column. Whenever that action is triggered, I want to execute "my action".

Without MVC, this would look like this:

        /* ... */
        {
            xtype: 'gridpanel',
            columns: [
                /* ... */
                {
                    xtype: 'actioncolumn',
                    items: [{
                        handler: function(grid, rowIndex, colIndex) {
                            // my action
                        }
                    }]
                }
            ]
        }

Now I want to introduce the View-Controller separation. So I have to move the handler from the View to the Controller.

But how does the controller register its method to the action column? Looking at the ExtJS 4.1 actioncolumn docs, I can't find any event I could listen to. I also can't find a method to set the action column's handler afterwards.

So how can I achieve a clean View-Controller separation when using an actioncolumn?

Are actioncolumns not yet ready for MVC?


Solution

  • The problem is not in actioncolumn but in its items which are not ExtJs Widgets. This items are simple images. That's why we cannot assign handlers in control in such a way:

    this.control({
        'mygrid actioncolumn button[type=edit]' : this.onEdit
    

    This way, however, would be the best one.

    Unfortunately this way is impossible. But There is another way, which is almost as clean as the preferred one: make actioncolumn handler to fire grid's custom event (created by you):

    // view
    {
        xtype: 'actioncolumn',
        items: [{
            icon: 'http://cdn.sencha.io/ext-4.1.0-gpl/examples/shared/icons/fam/cog_edit.png',
            tooltip: 'Edit',
            handler: function(grid, rowIndex, colIndex) {
                // fire custom event "itemeditbuttonclick"
                this.up('grid').fireEvent('itemeditbuttonclick', grid, rowIndex, colIndex);
            }},
    
    // controller
    init: function() {
        this.control({
            'viewport > testpanel': {
                itemeditbuttonclick: this.onEdit,
                itemdeletebuttonclick: this.onDelete
            }
        });
    },
    

    Example

    Here is demo.