Do we need to remove event listeners - angularjs

I am using the below event listener in my directive code in Angular JS to execute certain logic once that event is triggered:
element.on("change", function(e) {
//Logic goes here
}
I want to know whether do we need to manually destroy these listeners or will angular destroy their listeners. If we need to manually remove, could you help me how to remove these event listeners?

It will be removed automatically

Related

Backbone event propagation clarification

With the below code we are able to prevent handler1 from firing when clicking the second button.
var See = Backbone.View.extend({
events: {
'click': 'handler1',
'click .c2': 'handler2'
},
handler1: () => console.log('First handler'),
handler2: (e) => {
e.stopPropagation();
console.log('Second handler');
},
render: function() {
this.$el.html('<button>One</button><button class="c2">Two</button>');
return this;
}
});
How can this be? What path does the propagation take? Any insight would be much appreciated. Thanks!
In backbone, the events registered via view's event's hash are delegated to the respective view's el, except events which do not specify a selector which is registered directly on the view's el.
What path does the propagation take?
The propagation always takes the normal path - from the child to it's parents.
In this case the event bubbles from the button to the view element, when it reaches the view element the delegated click handler for the button is fired first 1 which prevents further propagation 2, So the direct handler on the view element is not invoked.
1 According to order-of-event-handling-in-jquery
In jQuery, delegates are privileged event handlers and are allowed to jump the queue. In fact, they are always stored in the front of the queue. This mechanism allows delegates to fire before direct events.
2 jQuery probably (because I didn't bother to check the source code to confirm, that's the way it should be) checks whether e.stopPropagation() have been called before invoking each handler to mimic normal bubbling.
propagation will flow from child to parent element if propagation is not stopped.
The First event you are listening to, is basically any click made inside the view area and is caught when it propagates to the view's root element.
The second event is caught whenever a click is propagated to the .c2 element, all DOM events propagate from the source element up to the parent.
If you stop the propagation in .c2, then the click will never reach the parent.
events: {
'click': 'handler1', // This catch clicks propagated to the view root
'click .c2': 'handler2 // this catch clicks in propagated to .c2 elem
},

Removing event listeners from a directive in AngularJS

I'm trying to realize a simple directive in AngularJS. In particular I want to develop a loader button that change its aspect when pressed, and I want to reuse it in all the page of my application that need it.
I have read on the developer guide that:
"There are a few special events that AngularJS emits. When a DOM node that has been compiled with Angular's compiler is destroyed, it emits a $destroy event. Similarly, when an AngularJS scope is destroyed, it broadcasts a $destroy event to listening scopes. By listening to this event, you can remove event listeners that might cause memory leaks. Listeners registered to scopes and elements are automatically cleaned up when they are destroyed, but if you registered a listener on a service, or registered a listener on a DOM node that isn't being deleted, you'll have to clean it up yourself or you risk introducing a memory leak."
In my link function I have put this code for the event listener:
var onLoaderButtonClickEvent = element.on('click', function(){
//Some stuff
});
Now, have I to consider that as a listener on a DOM element (and so I have to remove it) or not? I'm a lit bit confused.
I think that I have not to remove the listener because is on the "element". Is it correct?
Thx to all
The element.remove() is called automatically when a directive is destroyed, thus removing all listeners on the element. You only have to remove DOM listeners manually if you attached them to any other DOM elements.
From angular's documentation:
Listeners registered to scopes and elements are automatically cleaned up when they are destroyed, but if you registered a listener on a service, or registered a listener on a DOM node that isn't being deleted, you'll have to clean it up yourself or you risk introducing a memory leak.
The answer is yes. As you've attached an event handler outside of AngularJS, you'll need to clean it up yourself.
You can do this by listening to the $destroy event:
scope.$on('$destroy', function(){
element.off('click');
});

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
}
}
Firstly, it's important to understand the order events are fired:
render
itemclick
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.

event Ext.view.ViewView after Refresh

I need an event which will be fired when items in DataView are ready as DOM elements, when refresh() is fireing the items are still not ready
Thanks
viewready may not be used becouse it fires only onse, I need handle event after each refresh
I think viewready is what you are after. If this doesn't work, afterrender should.
If you need an event that fires AFTER refresh has completed then you can add one. Within the view component of your choice, or within a dataview override that would apply to all dataviews, override the refresh function, call its parent and fire a custom event when it's complete:
refresh : function () {
this.callParent(arguments);
this.fireEvent('afterrefresh')
}
You can listen for that event like any other e.g.
me.on({
afterrefresh : me.doSomethingAfterRefresh,
scope : me
});

How to cancel event of spinner field in ExtJS 4.1?

I am developing application using ExtJS 4.1. I have one spinner field and I want to change value of that method programatically. I have set up listeners like change, spinup and spindown for this same spinner field.
Now I would like to know how to prevent listener method of these events getting fired only when I change the value of spinner field through my program?
For example,
var mySpinner = Ext.ComponentQuery.query('#foopanel > #mySpinner')[0];
mySpinner.setValue(2000);
When mySpinner.setValue(2000); line is executed, change event of mySpinner gets fired and as I have listener method for this change event, that listener method is executed.
Is it possible to prevent invocation of change event listener method?
Thanks..
You could suspend all events by calling
mySpinner.suspendEvents();
mySpinner.setValue(2000);
mySpinner.resumeEvents();
That would be the cleanest an easiest way IMO
And that's also a usecase why this methods exist

Resources