1. #1
    Ext JS Premium Member Steffen Hiller's Avatar
    Join Date
    Mar 2008
    Posts
    773
    Vote Rating
    28
    Answers
    7
    Steffen Hiller will become famous soon enough Steffen Hiller will become famous soon enough

      0  

    Default Answered: How to set element listeners

    Answered: How to set element listeners


    What's the new way to set element listeners, such as:

    Code:
                    listeners: {
                        el: {
                            tap: function () {
                                console.log('tap');
                            }
                        }
                    }
    ?

    The console tells me:
    [ERROR][Ext.Container#addListener] Adding component element listeners using the old format is no longer supported. Please refer to: http://bit.ly/wYgr2q for more details.
    But the link http://bit.ly/wYgr2q or http://www.sencha.com/forum/showthre...onent-Elements is not working.

    Thanks.


  2. #2
    Sencha - Sencha Touch Dev Team rdougan's Avatar
    Join Date
    Oct 2008
    Posts
    1,158
    Vote Rating
    6
    Answers
    93
    rdougan will become famous soon enough

      0  
    Sencha Inc.
    Robert Dougan - @rdougan
    Sencha Touch 2 and Ext JS 4 Core Team Member, SASS/Theming Wizard.

  3. #3
    Ext JS Premium Member Steffen Hiller's Avatar
    Join Date
    Mar 2008
    Posts
    773
    Vote Rating
    28
    Answers
    7
    Steffen Hiller will become famous soon enough Steffen Hiller will become famous soon enough

      0  

    Default


    Cool, thanks.
    And now doing this using the new 'control' option in containers to have all listeners together.

    Anyway, I'm designing this new app following the principle of only having action methods in the controller and listeners in the views using control.
    The only blocker is setting listeners for the container itself via control, but should be overridable.
    Will look into it as soon as I really need it.

  4. #4
    Sencha User mbarrot's Avatar
    Join Date
    Jan 2012
    Location
    London, UK
    Posts
    8
    Vote Rating
    2
    mbarrot is on a distinguished road

      0  

    Default


    In PR4, the following code works as I expected:

    Code:
    Ext.define ('myapp.view.SampleView', {
        extend: 'Ext.Container',
        alias: 'widget.sample',
        config: {
            ...
            listeners: {
                tap: {
                    fn: function () {
                        console.log ('This component was tapped...');
                    },
                    element: 'innerElement'
                }
            },
            ...
        },
        ...
    });
    However I'm still confused on the the proper way to move this code to a controller, say 'myapp.controller.SampleController', in a more robust MVC architecture:

    How do I make sure the 'tap' event is fired for the container's 'Element' or 'innerElement' ?
    As a matter of fact, how do I reference the 'innerElement' of the 'sample' component from the controller ?

    Any help deeply appreciated...

  5. #5
    Sencha User mbarrot's Avatar
    Join Date
    Jan 2012
    Location
    London, UK
    Posts
    8
    Vote Rating
    2
    mbarrot is on a distinguished road

      1  

    Default


    I guess I found some answers on my own :-)

    In the view:
    Code:
    Ext.define ('myapp.view.SampleView', {
       extend: 'Ext.Container',
       alias: 'widget.sample',
       ...
       initialize: function () {
          var me = this;                                                                    
          this.element.on ({
             scope: me,
             tap: function (e, t) {
                me.fireEvent ('tap', me, me.getActiveItem (), e, t);
             }
          });
       }                                                                        
    });
    In the controller:
    Code:
    Ext.define ('myapp.controller.SampleController', {
       extend: 'Ext.app.Controller',
       config: {
          ...
          control: {
             'sample': {
                tap: function (component, activeItem, event, target) {
                   // tap handler code goes here.
                }
             }
          }
       }
    });
    I wonder if that's the best approach though. Does relaying the 'tap' event to the controller by re-firing it from the element listener instead of handling it there and then incur a discernable delay on 'less modern' devices ?

  6. #6
    Sencha User
    Join Date
    Jan 2012
    Posts
    8
    Vote Rating
    0
    Answers
    1
    garrettweinberg is on a distinguished road

      0  

    Question there must be a better way

    there must be a better way


    mbarrot, any further discoveries on this topic?

    The action handlers with parameters do indeed belong in the controller, but must events really be re-fired from the view in this way in order to have the parameters pass through to the controller? The "Refs and Control" docs concerning controllers have no example listeners that check which sub-item was tapped.

  7. #7
    Sencha User mbarrot's Avatar
    Join Date
    Jan 2012
    Location
    London, UK
    Posts
    8
    Vote Rating
    2
    mbarrot is on a distinguished road

      1  

    Default


    Well, I agree that in most cases, the event handler code belongs in a controller. Makes for a much cleaner architecture and more maintainable code this way.

    As I start to grasp Sencha Touch better, I seem to understand that 'tap' is a framework 'element' level event, where as the 'control' property of the controller only traps framework 'component' level events - I may be wrong - Robert orMitchell, please correct me.

    If such is the case, it does make sense to trap the event at element level, shift the scope to the component itself and refire it for the controller to catch:

    In the view:
    Code:
    initialize: function () {
        var me = this;                                                                    
        this.element.on ({
            scope: me,
            tap: function (e, t) {
                me.fireEvent ('tap', me, me.getActiveItem (), e, t);
            }
        });
    }
    In the controller:
    Code:
    config: {
        ref: {
            sample: 'container[cls="sample"]'    // or some other way to reference the component using Ext.ComponentQuery
        },
        control: {
            sample: {
                tap: function (component, activeItem, event, target) {
                    // tap handler code goes here.
                }
            }
        }
    }
    Check out http://docs.sencha.com/touch/2-0/#!/...ComponentQuery for more information on referencing components in the controller.

    I'm not sure what you mean by a 'sub-item'.

    If you mean a component embedded in the container, you should first reference it using ComponentQuery (this.query or this.down) in your container's initializing code, then use the 'on' property of its element to specify the event handler.

    Code:
    initialize: function () {
        me = this;
        var someItem = this.down('someComponentQuerySelector');                                                                    
        someItem.element.on ({
            scope: me,
            tap: function (e, t) {
                me.fireEvent ('tap', me, me.getActiveItem (), e, t);
            }
        });
    }
    Whether you want to handle the event in the controller at the container level (me.fireEvent) or at the inner component level (someItem.fireEvent) is debatable.

    As for performance issues of the component direct listener vs controller handling approach, I've run both codes on an iPhone 3GS and found both reasonably slow compared to a newer device :-) Slow enough not to notice any difference between the two. On an iPhone 4S, they are both pretty responsive, again, no real difference. I haven't any Android devices handy at the moment though...

    HTH. Marc

  8. #8
    Sencha User
    Join Date
    May 2012
    Posts
    34
    Vote Rating
    0
    pashute is an unknown quantity at this point

      -1  

    Default In Architect its easy

    In Architect its easy


    In Sencha Architect 2 its easy
    • In button's Config
    • search for - or mouse to Event Bindings
    • Add a basic handler
    • Choose Tap Event
    • Give name (onButtonDothisTap or whatever)
    • Convert to Action
    • Choose if new Controller (you give it a name) or existing controller
    • That's all folks, what's up doc?