53

在我的一个 Angular 控制器中,我有这个:

// controller A
$rootScope.$on("myEventFire", function(event, reload) {
    someAction();
});

在另一个控制器中,我有这个:

// controller B
$scope.openList = function(page) {
    $rootScope.$broadcast('myEventFire', 1);
}

现在,这是一个单页应用程序。当我最初去控制器 A 并尝试触发此事件时,someAction()将被执行一次。如果我离开并再次回到控制器 A 并做同样的事情,someAction()会执行两次。如果我再做一次,它会发生 3 次,依此类推。我在这里做错了什么?

4

5 回答 5

102

您可以尝试使用$scope.$on()吗?每次创建控制器 A 时,它都会在根范围上添加一个新的侦听器,并且在您离开和返回时不会被破坏。如果您在控制器的本地范围内执行此操作,则当您导航离开并且您的范围被破坏时,侦听器应该被删除。

// controller A
$scope.$on("myEventFire", function(event, reload) {
    someAction();
});

$broadcast将事件向下发送到所有子范围,因此应该在您的本地范围内拾取它。 $emit以另一种方式向根范围冒泡。

于 2013-10-23T22:45:30.387 回答
27

你也可以在作用域被销毁时移除它,方法是运行 $rootScope.$on() 的返回回调。

IE

var destroyFoo;

destroyFoo = $rootScope.$on('foo', function() {});

$scope.$on('$destroy', function() {
  destroyFoo(); // remove listener.
});       
于 2014-06-19T20:42:21.383 回答
9

如果你不想破坏,

我想我们可以先检查监听器事件——AngularJS 1.2.15

检查侦听器事件 - 示例

所以我认为这应该有效:

if(!$rootScope.$$listenerCount['myEventFire']){
    $rootScope.$on("myEventFire", function(event, reload) {
        someAction();
    });
}
于 2016-06-29T06:15:16.930 回答
3

如果它对任何人有帮助,我在指令中遇到了类似的问题。每次打开指令时,触发事件的次数都会增加。

我通过使用以下方法解决了它(这是在我的控制器初始化函数中,但我猜它可能已经在控制器本身中定义。在我的情况下,我的控制器需要在事件触发时重新初始化)

 if (!$scope.onMyEvent) $scope.onMyEvent= $scope.$on('myEvent',function(event,data){
        .....
        });
于 2017-08-16T09:32:30.943 回答
1

对于我的情况...

if ($rootScope.$$listenerCount['myEventFire']) {
    $rootScope.$$listeners.broadcastShowMessageError = [];
};

$rootScope.$on('myEventFire', function (event, reload) {
    someAction();
})
于 2017-01-11T10:28:58.417 回答