Angular js 多次订阅并触发多个事件

Angular js subscribe multiple times and fire multiple events

我正在为一个应用程序工作,我想与第三方 js 库通信 Angular js。为此,我使用了使用调解器 js 的 pubsub 方法。但是由于这个原因,当我订阅任何事件时,它都会订阅多次,因此当我发布事件时,它会触发多次。

我使用了以下代码:

angular.module('app')
   .service('mediator', function() {
     var mediator = window.mediator || new Mediator();
     return mediator;
 });

// Main controller begins here
  angular.module('app').controller('MainController', MainController);
  MainController.$inject = ['mediator'];

  function MainController(mediator){
    var vm = this;
    vm.title = "This is main controller."

    vm.sendMessage = function(){
      mediator.publish('something', { data: 'Some data' });  
    }


  }


  // First page controller begins here
   angular.module('app').controller('FirstController', FirstController);
  FirstController.$inject = ['mediator'];

  function FirstController(mediator){
    var vm = this;

    console.log('Subscribed events for first controller.');

    var counter = 0;
    mediator.subscribe('something', function(data){ 
      console.log('Fired event for '+ counter.toString());
      counter = counter + 1;
    });

  }

为了更好的解释,这里是 plunker: Plunkr

测试这个插件:

  1. 运行 笨蛋。
  2. 打开开发者控制台。
  3. 点击第一页
  4. 点击触发事件
  5. 点击第二页
  6. 点击第一页
  7. 点击触发事件

当您第二次导航到第一页时,它将再次订阅事件并触发两次。当您多次导航到第一页时,这将多次订阅。

如果我做错了什么,请告诉我。

控制器销毁后可以退订

要使用调解器执行此操作,您首先需要保存订阅功能:

var sub = function(data){ 
  console.log('Fired event for '+ counter.toString());
  counter = counter + 1;
}
mediator.subscribe('something', sub);

然后您可以使用angular事件取消订阅控制器移除时的通知:

$scope.$on("$destroy", function() {
    mediator.remove("something", sub);
});

无论何时使用此模式,您都应该考虑需要删除订阅的时刻,这不仅是出于重复的原因,而且还可能导致内存泄漏。

别忘了你还需要注入$scope(即使不使用它作为模型的持有者,注册事件监听器也可以):

angular.module('app').controller('FirstController', FirstController);
FirstController.$inject = ['mediator', '$scope'];

Plunkr 示例:https://plnkr.co/edit/CgYLLSxGF2Fww5vBB7PB

希望对您有所帮助。