【发布时间】:2017-01-03 07:01:48
【问题描述】:
我正在为一个应用程序工作,我想将 Angular js 与第三方 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
要测试这个 plunker:
- 运行 plunker。
- 打开开发者控制台。
- 点击首页
- 点击触发事件
- 点击第二页
- 点击首页
- 点击火灾事件
当您第二次导航到第一页时,它将再次订阅事件并触发两次。当您多次导航到第一页时,这将订阅多次。
如果我做错了什么,请告诉我。
【问题讨论】:
-
您当前将在每次加载控制器时订阅,这将是每次您导航到页面时。这似乎是一个跟踪您是否订阅的简单案例,并使用
if(!subscribed)或类似名称。 -
好吧,当你的控制器被销毁时,你并没有取消订阅。所以它一直被订阅。你不仅有多个控制台日志,还有一个很好的内存泄漏。
-
@JBNizet:您能告诉我们,如何使用调解器 js 取消订阅事件吗?
-
请注意,角度范围具有本机事件机制。如果您使用标准的 $scope 机制来广播和收听事件,那么 Angular 会为您处理好这件事,因为控制器的 $scope 会随控制器一起销毁。
-
仅仅因为您没有为 变量属性 主动注入
$scope并不意味着它没有在 Angular 内部使用,或者您不能在需要时注入它,例如广播/发射。 “$scope很糟糕”的口头禅通常被误解,并不完全正确。