1
votes

Today I have a small question regarding what the correct/best way is to add listeners using Sencha Touch 2 via it's recommended MVC model.

As far as I can see, there are two main ways that I have been presented with to add listeners to the various components across my views.

1. In the controller.

I came across this method while reading the MVC documents for ExtJS 4.0 (no MVC docs for touch yet). It goes like so:

init: function() {
        console.log ('Launched the controller');

        //listening test
        //the Control function/method is unique to controllers and is used to add listeners to stuff
        this.control({
            'button': { 'tap' : function (){
                console.log('the buttons speak!');
                }
            },
}

The above code would reside inside the main controller, for instance. Here, as you can see, I am adding a "tap" listener to ALL buttons across the entire app.

As far as I know, to access specific components in this way, I would need to tag them each with a unique ID and then use componentquery at this location to place listners onto them.

Question: I think this method is pretty cool... but I have run across problems using it in lists... sometimes I want to listen to a specific list item for things like "tapstart" and "tapend" but since usually listItems are dynamically created as children to a list... I have no idea how to give them unique IDs and/or find them using the query engine (due to my inexperience I guess? I haven't been able to google/find anything about it in the docs that makes sense).

2. During the init/config of individual components

The other method that I came across to add listeners to components is to define the listener, it's callback and the event it's listening to directly in the component config.

Example:

Ext.define('Paythread.view.CommentList', {

    extend: 'Ext.Panel',    
    alias: 'widget.CommentList',
    layout: 'vbox',
    config : {
        items: [    
            { 
                xtype: 'list', 
                layout: 'fit', //fullscreen: true, 
                height: 'viewport.height',
                store: 'Comments',
                onItemTap: function(){
                    //do stuff
                },
                pressedDelay: 20, //HOLY CRAP IMPORTANT FOR UX
                itemTpl: '<h1>{user_id}</h1><h2>{comment}</h2>'
            }

        ]       
    }, 
});

As you can see from this code, I have created a "onItemTap" listener function, and this seems to work pretty darn well. However... it scares me for some reason and I have no idea if what I am doing is correct or not.

Could anyone provide some help as to whether I am doing the right thing, if I should be doing this a different way, or if I am completely off track and shouldn't even be defining listeners like this in the first place?

I would really appreciate any help given! Thank you very much everyone.

4

4 Answers

1
votes

The following method to add listeners looks a bit clearer to me:

Ext.define('Paythread.view.CommentList', {

    extend: 'Ext.Panel',    
    alias: 'widget.CommentList',
    layout: 'vbox',
    config : {
        items: [    
            { 
                xtype: 'list', 
                layout: 'fit', //fullscreen: true, 
                height: 'viewport.height',
                store: 'Comments',
                listeners: {
                    itemtap: function() {
                        //do stuff
                    }
                }
                pressedDelay: 20, //HOLY CRAP IMPORTANT FOR UX
                itemTpl: '<h1>{user_id}</h1><h2>{comment}</h2>'
            }
        ]       
    }
});

The tap function will be called when the list is tapped. AS simple as it sounds. Hope it helps,

Chris

1
votes

since you ask about listening to events on a list item, you should probably check out: http://www.sencha.com/blog/event-delegation-in-sencha-touch

Unfortunately, the syntax is changed a bit with ST2. See this thread: http://www.sencha.com/forum/showthread.php?154513-How-to-buffer-events-without-using-addListener

1
votes

you have to add itemId propety in your list and by using this itemId you can get object of list and after that you can add listeners like this

init: function() {
    console.log ('Launched the controller');

    //listening test
    //the Control function/method is unique to controllers and is used to add listeners to stuff
    this.control({
        Paythread.view.CommentList.query('itemIdof List')[0].on({
               itemtap: function() {
                    alert('test')
                }

              });
        },
}

this may help you

Thanks

1
votes

There are several ways of adding listeners, and I think that there are a couple of considerations on each approach:

Should I put the listeners on the controller or on the view??

For me, that depends; if your view is basically a component that you are going to re-use, you probably want to tie up elements with events. Although, you should not put the logic of the event on the view. Instead, your view should fire an event that can be listened by the controller.

Example:

Ext.define("App.view.SomePanel", {
  extend: "Ext.form.Panel",
  xtype: "somepanel",
  config:{
      scrollable:'vertical' ,
  },
  initialize: function () {
    var backButton = {
        xtype: "button",
        ui: "back",
        text: "Home",
        handler: this.onBackButtonTap,
        scope: this
    };

    this.add([
      {
        xtype: "toolbar",
        docked: "top",
        title: "Edit Player",
        items: [ backButton ]
      }
    ]);
  },
  onBackButtonTap: function () {
      this.fireEvent("goBackCommand", this);
  }
});

On this panel, we have a back button. The view shouldn't handle what the back button does (as it depends on the flow of the app rather than the view itself) but it should fire an event that we can catch on the controller.

Another very important thing that you should always take into consideration, is the scope of the the listener. Basically, the scope means what value this will have in the function triggered by the event. (In this example, the view itself)

Hope this helps!

Edit: link to Sencha guide about events:

http://docs.sencha.com/touch/2-0/#!/guide/events