Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
702 views
in Technique[技术] by (71.8m points)

angularjs - Difference between $rootScope.$on vs $scope.$on

Can someone help me understand the way when we should use $rootScope.$on and $scope.$on.

I know that its mostly for hearing different scope ($rootScope and $scope).

My query is for below Scenario:

Shall I use : $rootScope.$emit with $rootScope.$on

OR

Shall I prefer: $rootScope.$broadcast with $scope.$on I know this will be not a good option as it'll broadcast to all $scope obj.

OR

Shall I go for: $rootScope.$broadcast with $rootScope.$on

As you can see, I need to handle event on $rootScope level.

What is the difference in above 3 implementations ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is a good questions and there is an explanation for you.

First of all note that:

  • $scope.on('event'); will listen to $scope.$broadcast('event') & $rootScope.$broadcast('event')

  • $rootScope.on('event'); will listen to $rootScope.$broadcast('event') & $rootScope.$emit('event')

Next you need to note that:

  • $scope.on(); will be destroyed automatically when the controller loses it representation in view or component (getting destroyed).
  • You need to destroy $rootScope.$on() manually.

>> Example of how to destroy $rootScope.on():

//bind event
var registerScope = $rootScope.$on('someEvent', function(event) {
    console.log("fired");
});

// auto clean up `$rootScope` listener when controller getting destroy
// listeners will be destroyed by calling the returned function like registerScope();
$scope.$on('$destroy', registerScope);

>>> Since Angular v1.5 we can use component lifecycle to manage init and destroys in a nice way:

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function ($scope, $rootScope) {

  var registerScope = null;

  this.$onInit = function () {
    //register rootScope event
    registerScope = $rootScope.$on('someEvent', function(event) {
        console.log("fired");
    });
  }

  this.$onDestroy = function () {
    //unregister rootScope event by calling the return function
    registerScope();
  }
});

This plnkr will show you the different behaviors of $scope.on() and $rootScope.on().

By switching the view in this plunkr the controller will be rebinded to your view. The $rootScope.on(); event is binded every time you switch a view without destroying the event bindings of the view before. In that way the $rootScope.on() listeners will be stacked/multiplied. This will not happen to the $scope.on() bindings because it will be destroyed by switching the view (losing the E2E binding representation in DOM -> controller is destroyed).

The difference between $emit & $broadcast is:

  • $rootScope.$emit() events only triggers $rootScope.$on() events.
  • $rootScope.$broadcast() will trigger $rootScope.$on() & $scope.on()events (pretty much everthing hear this event).
  • $scope.$emit() will trigger all $scope.$on, all its parents (scopes in parent controllers) and $rootScope.$on().
  • $scope.$broadcast will only trigger $scope and its children (scopes in child controllers).

Additional Links


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...