$ rootscope。$ on增加订户数量

时间:2014-05-28 20:36:24

标签: javascript angularjs

我有一个Angular控制器,一个相当简单的控制器:

angular.controller('appCtrl', function ($scope, $rootScope) {
    $rootscope.$on('channel.message', function () {
      // do stuff here
    }
}); 

我的页面上有一些侧边栏,它会导航我到上面附带控制器的视图。

问题在于,每次点击链接时,Angular都会实例化控制器 - 这完全没问题,但我可以看到我'channel.message'的订阅者数量正在增长,这不是我想要的是。

我理解,嗯,代码只是添加了另一个回调队列,但我希望避免这个问题。我只想要一个订阅者。这里的最佳做法是什么?

BTW:我知道 $ scope 。$ on。由于应用程序本身的性能影响和架构设计,它不算数。

3 个答案:

答案 0 :(得分:3)

也许尝试在命名函数中调用您的事件处理程序,该函数将调用它并清理它。这样的事情(同样,确保$rootscope $rootScope ):

angular.controller('appCtrl', function ($scope, $rootScope) {
    var cleanUp = $rootScope.$on('channel.message', function () {
        // do stuff here
    };

    cleanUp();
});

我遇到了同样的问题(多个回调被添加到队列中),上面的解决方案对我有用。


此外,这是偏离主题,但我可能会建议您按如下方式格式化控制器(仅建议):

angular.controller('appCtrl', ['$scope','$rootScope', function($scope, $rootScope) {

}]);

答案 1 :(得分:2)

由于@JoshBeam指出$ rootScope的返回值。$ on()是一个取消注册你的监听器的函数。他指出:

var cleanUp = $rootscope.$on('channel.message', function () {
   // do stuff here
}

剩下的问题是何时触发清理。您很可能只想在销毁控制器时取消注册。令人高兴的是,在Angular撕下一个范围之前(例如,由于被破坏的控制器),它会在该特定范围内触发$destroy event。因此,您可以使用以下命令触发清理。

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

请注意,仅出于拆除目的,我们正在$destroy上监听$scope(而不是$rootScope),以便在控制器拆除时收到消息。您可以将常规侦听器附加到$rootScope

另请注意,这也是用于防止内存泄漏的良好模式 - 即使您不担心多个侦听器。

答案 2 :(得分:1)

我建议按照我在这里的回答中所述创建一个$onRootScope方法:

What's the correct way to communicate between controllers in AngularJS?

这会自动抽象出事件处理程序的注销,使用情况就像$scope.$onRootScope('fooEvent', function(){})

一样简单

另请注意,最近版本的角度广播事件的性能影响不大。