I have a directive that contains in his controller a watcher like:
$rootScope.$on('broad1', (event, args) => {
doSomething()
});
Then, I reload (with $state.go) a part of my page that contains my directive. And unfortunately, even if my directive is reinit and of course, not duplicated, a new watcher is created and added in my rootscope. ( I already know that when watcher are attached to rootscope, isn't destroyed whereas the directive is removed from DOM)
So, when I broadcast 'broad1' the watchers are executed n times (corresponding to n previous reloads). WHY?
When using the AngularJS event bus in directives, events listeners should be placed on local scope. Events should be broadcast from $rootScope
:
app.directive("myDirective", function() {
return {
link: postLink,
};
function postLink(scope,elem,attrs) {
scope.$on('broad1', (event, args) => {
doSomething()
});
scope.broadcast = function(data) {
scope.$root.$broadcast("broad1", data);
};
};
})
When the scope is destroyed the event listener will automatically be removed.
For more information, see
Keep in mind the the AngularJS event bus is inefficient and obsolete. Whenever possible use more direct ways to communicate events to their recipients.
From the Docs:
Only use .$broadcast() and .$on() for atomic events
Events that are relevant globally across the entire app (such as a user authenticating or the app closing). If you want events specific to modules, services or widgets you should consider Services, Directive Controllers, or 3rd Party Libs
- Injecting services and calling methods directly is also useful for direct communication
- Directives are able to directly communicate with each other through directive-controllers
See also,