-
24 Jan 2012 12:02 PM #1
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:
But the link http://bit.ly/wYgr2q or http://www.sencha.com/forum/showthre...onent-Elements is not working.[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.
Thanks.
Owner of 360releases Ltd. - Sencha Touch & Ext JS consulting
twitter.com/steffenhiller
extjswithrails.com, senchatouchbits.com
-
Best Answer Posted by rdougan
-
24 Jan 2012 12:32 PM #2Sencha Inc.
Robert Dougan - @rdougan
Sencha Touch 2 and Ext JS 4 Core Team Member, SASS/Theming Wizard.
-
24 Jan 2012 1:04 PM #3
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.Owner of 360releases Ltd. - Sencha Touch & Ext JS consulting
twitter.com/steffenhiller
extjswithrails.com, senchatouchbits.com
-
24 Jan 2012 3:31 PM #4
In PR4, the following code works as I expected:
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: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' } }, ... }, ... });
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...
-
26 Jan 2012 9:22 AM #5
I guess I found some answers on my own :-)
In the view:
In the controller: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); } }); } });
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 ?Code:Ext.define ('myapp.controller.SampleController', { extend: 'Ext.app.Controller', config: { ... control: { 'sample': { tap: function (component, activeItem, event, target) { // tap handler code goes here. } } } } });
-
8 Feb 2012 2:46 PM #6
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.
-
9 Feb 2012 1:41 AM #7
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:
In the controller:Code:initialize: function () { var me = this; this.element.on ({ scope: me, tap: function (e, t) { me.fireEvent ('tap', me, me.getActiveItem (), e, t); } }); }
Check out http://docs.sencha.com/touch/2-0/#!/...ComponentQuery for more information on referencing components 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. } } } }
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.
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.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); } }); }
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
-
9 Jun 2012 11:59 PM #8
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?


Reply With Quote