2

I heard its a bad practice to use rootscope $on from a controller, because when a controller is destroyed, the event listener is not. If I use it from a service and inject it to the controller, like below, will it prevent memory leaks?

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})
Mister_L
  • 2,469
  • 6
  • 30
  • 64

1 Answers1

2

I don't think this is going to 'prevent' memory leaks because it never gets destroyed through out the lifetime of the application because every even is getting registered on $rootScope.

Best practice would be to destroy the listener on scope destruction.

For example, if there is a controller that's listening to an event like so,

$scope.$on('anEvent', function(){});

there is no need to destroy the listener as the listeners will be automatically unregistered on scope destruction, automatically.

On the other hand if the event is registered on $rootScope,

var eventHandle = $rootScope.$on('anEvent', function(){});

the even can be (and should be) destroyed by executing the eventHandle (which is a function) on scope destroy:

$scope.$on('$destroy', function(){
    eventHandle();
});

And also, try to avoid broadcasting events on $rootScope. Try using $emit and $broadcast on child scopes. More info: $rootScope.$broadcast vs. $scope.$emit

Community
  • 1
  • 1
Chanthu
  • 1,794
  • 1
  • 15
  • 22
  • In that case, why do they say it is best practice to put the event dispatcher/listener in a service? @Chanthu – Mister_L Jan 18 '16 at 11:55
  • I guess one reason might be that the `api` would be a lot cleaner. The method that's getting invoked would have a meaningful name, no need to duplicate the event name. Other than that, not sure. – Chanthu Jan 18 '16 at 12:25