Jacobian
Jacobian

Reputation: 10842

How to remove a listener before an event takes place?

My question is similar to this one: How to prevent itemclick event on check change in Ext Js Tree.

However, it does not provide a solution for my problem. So, my question is: how can I remove a listener before an event takes place? The problem is that I have three listeners in my tree, and on checkchange I want to prevent the itemclick event. But everything executes in an unexpected order. The code is:

checkchange:function(node,check){                           
  alert("1");
},
itemclick:function(view,rec,item,index,eventObj){
  alert("2");
},
render:function(){
  Ext.getCmp('mytree').on('checkchange',function(node,check){
    alert("0");
    Ext.getCmp('mytree').removeListener('itemclick',this);
  });
}

When I check a node in my tree, I first see alert(2), then alert(1) and only then alert(0). So, the code which should remove the listener happens at the very end and I want the opposite.

Edit:

I do not want to completely remove the itemclick event. The more appropriate word is to "stop" an event, to prevent it from happening.

Edit:

The solution is to do e.getTarget() check inside the itemclick event. So, my code inside the itemclick event now looks like this:

itemclick:function(view, record, item, index, e, eOpts){
  if(e.getTarget('span',1,true)){
     // all other code which should take place in case
     // itemclick event does not come from checkbox element
  }
}

Upvotes: 0

Views: 11508

Answers (1)

SW4
SW4

Reputation: 71190

Firstly, it's important to understand the order events are fired:

  1. render
  2. itemclick
  3. checkchange

Secondly, it's important to understand what's happening within the function you've defined for the render event.

What the code is doing is adding additional code to that which you've already defined for the checkchange function, so checkchange when it runs will alert 1 then 0 (what you are seeing). In addition, it will then remove the itemclick listener. This will mean that the second time you click a node, it should behave differently.

If you want to suppress the itemclick event immediately upon render, you should un-nest the removeListener call, thus:

render:function(){
  this.removeListener('itemclick',this).on('checkchange',function(node,check){
    alert("0");    
  });
}

Alternatively, you can simply remove the itemclick event listener itself.

If you want to change the way the itemclick event is handled, you can also intercept the event itself, using one of these methods:

itemclick:function(view,rec,item,index,eventObj){
  eventObj.preventDefault(); //or
  eventObj.stopPropagation(); //or
  eventObj.stop();
},

It's not clear what you're trying to accomplish, however.

Upvotes: 2

Related Questions