指令的 $rootScope.$on 事件侦听器残留问题

Directive's $rootScope.$on event listener remanent issue

我有一个指令,在他的控制器中包含一个观察者,例如:

$rootScope.$on('broad1', (event, args) => {
            doSomething()
});

然后,我重新加载(使用 $state.go)包含我的指令的页面的一部分。不幸的是,即使我的指令被重新初始化并且当然没有被复制,一个新的观察者也会被创建并添加到我的根范围中。 (我已经知道,当 watcher 附加到 rootscope 时,不会被破坏,而指令已从 DOM 中删除)

所以,当我广播 'broad1' 时,观察者被执行了 n 次(对应于之前的 n 次重新加载)。为什么?

在指令中使用 AngularJS 事件总线时,事件 listeners 应该放在 local scope 上。事件应 $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);
        };
    };
})

当作用域被销毁时,事件侦听器将被自动删除。

有关详细信息,请参阅


更新

请记住,AngularJS 事件总线效率低下且已过时。尽可能使用更直接的方式将事件传达给他们的收件人。

来自文档:

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

AngularJS Wiki - Best Practices

另见,

感谢您的反应和洞察力,我已经使用 $scope.on[...] 和 $rootscope.broadcast[...] 修复了它。 另一方面,"service way" 也不错。

祝你有愉快的一天。