I do not even want to admit how much time I spent today in a more complex application trying to get a button to respond to a tap event in SenchaTouch 2.0 Beta. I did notice several people like me on the forums with similar issues, but I did not find one concrete example that made the simple “click a button application”. Of course I’m building this in Microsoft Visual Studio 2010 and debugging with Chrome. Let me start at the end. When you are done, you will have a simple two button page that you can click on either button and have your MVC controller react to either button as well as trap the button hit inside the actual Panel.
And for those of you that have read enough, here is the source:
The Nitty Gritty
Creating an SenchaTouch project with MVC is a little tricky to setup. You need to get all the directories right. My favorite way to do this is to use the Sencha Designer to create the project, then abandon it if I want to strike out on my own. That is what I’ve done here. I don’t even think you can tell.
Here is the file layout as seen from Visual Studio:
5 Files and 3 directories.
Let’s first take a look at the Panel that contains the buttons. Here is the code:
Ext.define('MyApp.view.MyPanel', { extend: 'Ext.Panel', alias: 'widget.mypanel', config: { items: [ { xtype: 'button', itemId: 'mybutton1', text: 'MyButton1', action: 'b1' }, { xtype: 'button', itemId: 'mybutton2', text: 'MyButton2', action: 'b2' } ],listeners: [ { fn: <span class="str">'onMybutton1Tap'</span>, <span class="kwrd">event</span>: <span class="str">'tap'</span>, <span class="kwrd">delegate</span>: <span class="str">'#mybutton1'</span> } ] }, onMybutton1Tap: <span class="kwrd">function</span> (button, e, options) { console.log(<span class="str">'tap from mybutton1'</span>); }
});
Just a couple things to notice. 1) I’m defining an itemId which we will only be using in the local event (onMybutton1Tap). If you notice the listener has a property delegate which looks for that. I’m not sure if this is the best way to do this. I’ve notice several forum people saying use the “on” syntax. I did not find an example of that so this is what we have and it works. Also notice the action property. If you try and look that up on the SenchaTouch doc’s you will not find it. I just made it up out of thin air (really!, well, I followed others examples). I actually asked about this in the forums and I was told that is OK. As a type safe language guy, it hurts, but I did it.
That’s it for the view. Let’s move over to the controller. Here is the source for that:
Ext.define('MyApp.controller.MyController', { extend: 'Ext.app.Controller',views: [ <span class="str">'MyPanel'</span> ], refs: [ { <span class="kwrd">ref</span>: <span class="str">'MyPanel'</span>, selector: <span class="str">'mypanel'</span> }], init: <span class="kwrd">function</span> () { <span class="kwrd">this</span>.control({ <span class="str">'button[action=b1]'</span>: { tap: <span class="kwrd">this</span>.onButtonTap1 }, <span class="str">'button[action=b2]'</span>: { tap: <span class="kwrd">this</span>.onButtonTap2 } }); }, onLaunch: <span class="kwrd">function</span> () { console.log(<span class="str">'onLaunch'</span>); }, onButtonTap1: <span class="kwrd">function</span> () { console.log(<span class="str">'controller: onButtonTap1'</span>); }, onButtonTap2: <span class="kwrd">function</span> () { console.log(<span class="str">'controller: onButtonTap2'</span>); }, config: { }
});
Basically, what this is doing is filtering all buttons, then looking at just the buttons that have an action of b1 or b2. If this was a large application, we’d probably want to do some more fancy component querying, but for now, this is OK. If you keep your controllers small, this should always work.
That’s it for now. Download the source and run it. I hope it saves you a ton of time.
As always any experts want to comment and improve or correct what I’ve done, please feel free to comment.