Search code examples
javascriptextjsextjs4

ExtJs removing and adding listeners. Caching issue


I have an object wich caches windows with all their internal structure (form, other ui elements). So when a user opens a window which has already been cached, it does create it from scratch, but takes if from cache and just show it like this:

winCache[id_group].show();

So, for each id_group, there is a window which may be cached in winCache. The problem is that I want to reset a form, which is inside the window, and populate it with new data from database. I try to do it like this:

if(winCache[id_group]){
    winCache[id_group].removeListener('show');
    winCache[id_group].addListener('show', function () {
      populate_form(this, id_field); // <-- this method retreives data from database 
   // and sets the form  
    });
    winCache[id_group].show();  
}
else { // window was not cached and has to be created from scratch
  var win = ...
  win.show();
  // ... some BIG procedure
  winCache[id_group] = win; // next time it will be taken from cache
}

But the problem is, for some insane reason, ExtJS duplicates show listeners infinitely. So, for example, if I open winCache[10] seven times for the same id_group = 10, but for different id_fields (id_field = 1, id_field = 2, ..., id_field = 7), then show listener will be triggered seven times - for each id_field. And that is incredible stupidity. So, my question is why ExtJS duplicates listeners? And why doesn't removeListener work???


Solution

  • The removeListener expects a function reference as the second argument.

    If this code you've added is executed each time the window should be displayed may be using single: true on the addListener will solve your issue (so you don't need to removeListener), try:

    winCache[id_group].addListener('show', function () {
    
    }, null, { single: true });
    

    If that's not the case, you'll need to save a reference to the show function you'r passing to addListener so you'll be able to pass it to removeListener, or may be use destroyable, like:

    winCache[id_group].destroyShowEvent && winCache[id_group].destroyShowEvent.destry();
    winCache[id_group].destroyShowEvent = winCache[id_group].addListener('show', function () {
    
    }, null, { destroyable: true });