When buttons are removed they lose event handling in Sencha Touch 2.3

539 views Asked by At

I have a class called SettingsBar that extends TitleBar in Sencha Touch 2.3. This SettingsBar I'm using has several buttons on it. When you click the Settings button then the bar is added to the panel and it shows up just fine.

You can click the buttons on the SettingsBar and different things will happen in the app. I have it setup so that you can make the SettingsBar disappear if you click the Settings button again. So the Settings button adds and removes the SettingsBar.

When the SettingsBar is added, and you click some of the buttons, then the SettingsBar is removed, the state of the SettingsBar isn't saved. The buttons go back to their original text (their text changes when you click them) and the event handling for them no longer works. You just click them and nothing happens.

Here's my code that adds and removes the SettingsBar:

settingsTap: function(){
      if(settingsToolbar.added){

          Ext.getCmp('mainview').removeAt(2);
          console.log('added: '+settingsToolbar.added);

      }else{

          Ext.getCmp('mainview').add(settingsToolbar);
          console.log('added: '+settingsToolbar.added);

      }

      settingsToolbar.added = !settingsToolbar.added;
}

The event handling is being done in my controller. Why would the buttons be reset and event handling on them removed when the SettingsBar is removed from the panel?

2

There are 2 answers

0
Thiem Nguyen On

This is troublesome and has been asked for several times.

The safest way which even works when you destroy the component completely when removing it (you should always do, it reclaims a lot of memory), is to declare the event handlers in the initialize function of that component, or its parent component, wherever you think suitable, for example:

initialize: function(){
    var me = this;
    me.add({
        xtype: 'list',
        grouped: true,
        indexBar: true,
        itemTpl: '{first} {last}',
        listeners: [
            {
                event: 'itemtap',
                fn: function(dataview, index, target, record, e){
                    // do something
                }
            }
        ]
    });
}

This is an example for itemtap event on a Ext.List. Let's adapt it to your case.

2
rixo On

By default, child components are destroyed when they are removed from a container. When speaking of Ext components, "destroy" means removing all listeners and references, so that the object can be cleaned out by the garbage collector.

You can prevent destruction of removed components by changing the autoDestroy option of the container (the title bar, in your case). Don't forget however that you'll have to call the destroy method of each components yourself when you're done with them, or you'll be creating a memory leak in your app.