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

前端 未结 1 1786
予麋鹿
予麋鹿 2020-12-09 13:23

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

相关标签:
1条回答
  • 2020-12-09 13:50

    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

    • Do you need to unbind $scope.$on in $scope $destroy event?
    0 讨论(0)
提交回复
热议问题