Reputation: 33059
I saw a piece of code in a controller recently that went something like:
.controller('foobar', ['$scope', '$rootScope', function($scope, $rootScope) {
var eventHandler = $rootScope.$on('some-event', function() {
...
});
// remove eventHandler
$scope.$on('$destroy', eventHandler);
}]);
Questions:
eventHandler
"deregistration" function on $scope
's $destroy
event necessary?$scope
's $destroy
event have been necessary if 'some-event'
was $on
$scope
instead of $rootScope
?Any advice about understanding this snippet/"deregistration" would be much appreciated.
Upvotes: 1
Views: 2167
Reputation: 1790
In the example above the destroy method is necessary. The listener is bound to the $rootscope
which means that even after the controller gets $destroy
-ed the listener is still attached to the dom through the $rootscope
. Every time the controller is instantiated a new eventhandler will be created so without the destroy method you will have a memory leak.
However if you bind the listener to the controllers $scope
it will get destroyed along with the controller as the $scope gets destroyed so the listener has no connection to the dom thus making it eligible for garbage collection
Upvotes: 4
Reputation: 1561
$destroy
event when it is on that controller's $scope
.$scope
since that's handled for you by Angular.element
, controller
, or service
you are listening on then that is when you need to handle deregistering yourself. A good example is a directive that registers event listeners on the $document
:
var module = angular.module('test', []);
module.directive('onDocumentClick', function directiveFactory($document) {
return {
link: function (scope, element, attrs) {
var onDocumentClick = function () {
console.log('document clicked')
};
$document.on('click', onDocumentClick);
// we need to deregister onDocumentClick because the event listener is on the $document not the directive's element
element.on('$destroy', function () {
$document.off('click', onDocumentClick);
});
}
};
});
Upvotes: 1