1. #1
    Sencha User
    Join Date
    Jul 2011
    Posts
    22
    Vote Rating
    0
    Answers
    3
    I'm Dennis is on a distinguished road

      0  

    Question Answered: MVC: Controller reference from Grid's Action Cell handler.

    Answered: MVC: Controller reference from Grid's Action Cell handler.


    How to get Controller's object reference from grid's actioncolumn's cell handler?

    I have an application and have method defined in controller
    Code:
    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:
    Code:
    {
            ... 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.

  2. hi dennis,

    action columns have the method:
    Code:
        /**
         * @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".

  3. #2
    Sencha Premium Member tobiu's Avatar
    Join Date
    May 2007
    Location
    Munich (Germany)
    Posts
    2,695
    Vote Rating
    114
    Answers
    130
    tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all

      0  

    Default


    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:
    http://docs.sencha.com/ext-js/4-0/#!...ComponentQuery

    and also into the controller definitions:
    http://docs.sencha.com/ext-js/4-0/#!...app.Controller

    like:
    Code:
    Ext.define('MyApp.controller.Users', {
        extend: 'Ext.app.Controller',
    
        init: function() {
            this.control({
                'viewport > panel': {
                    render: this.onPanelRendered
                }
            });
        },
    
        onPanelRendered: function() {
            console.log('The panel was rendered');
        }
    });
    Best regards
    Tobias Uhlig
    __________

    S-CIRCLES Social Network Engine

  4. #3
    Sencha User
    Join Date
    Jul 2011
    Posts
    22
    Vote Rating
    0
    Answers
    3
    I'm Dennis is on a distinguished road

      0  

    Default


    Thanks, tobiu

    But in my case it's probably better to fire some custom event during click on action columns action button like this:
    Code:
    ...
        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?

  5. #4
    Sencha Premium Member tobiu's Avatar
    Join Date
    May 2007
    Location
    Munich (Germany)
    Posts
    2,695
    Vote Rating
    114
    Answers
    130
    tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all tobiu is a name known to all

      0  

    Default


    hi dennis,

    action columns have the method:
    Code:
        /**
         * @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".
    Best regards
    Tobias Uhlig
    __________

    S-CIRCLES Social Network Engine

  6. #5
    Sencha User
    Join Date
    Jul 2011
    Posts
    22
    Vote Rating
    0
    Answers
    3
    I'm Dennis is on a distinguished road

      0  

    Default


    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

Thread Participants: 1

Tags for this Thread