Plnkr示例构建:http://plnkr.co/edit/gB7MtVOOHH0FBJYa6P8t?p=preview
Following the answer here,我创建了一些$broadcast
个事件,以允许主$scope
中的操作关闭子$scopes
中的弹出窗口。但是我想确保我清理所有的事件而不会有任何不应该留下的事情。
我有一个popover指令,一旦弹出窗口被激活,我发出:
vs.$emit('popoverOpen');
然后在主应用程序模块($ rootScope)中,我在这里听取它:
vs.$on('popoverOpen',function(events,data) {
// if 'popoverOpen' is heard, then activate this function
// which on click $broadcasts out even 'bodyClick'
// but also destroy the 'popoverOpen' event
vs.bodyClick = function() {
$rootScope.$broadcast('bodyClick');
$rootScope.$$listenerCount.popoverOpen=[];
};
});
回到popover指令中,这是我的bodyClick
听众:
vs.$on('bodyClick', function() {
vs.searchPopoverDisplay = false;
$rootScope.$$listenerCount.bodyClick=[];
});
^我也有代码试图杀死bodyClick
事件,但无济于事:(
如下所示,我已从bodyClick
中移除了popoverOpen
和$$listenerCount
($$listener
对象中没有任何内容。
但是,即使vs.bodyClick()
已被删除,用户仍然可以访问主应用rootScope中的popoverOpen
功能。
首次加载:
bodyClick
bodyClick
处于活动状态bodyClick
事件不断发送的正文
在发送bodyClick
事件以关闭弹出窗口后,您如何正确删除事件?
更新 我也尝试了这个(https://github.com/toddmotto/angularjs-styleguide#publish-and-subscribe-events),但是当弹出窗口关闭并且据说被破坏后,bodyClick事件仍然会被发送出来。
仍会调用popoverDirective函数:
vs.$on('bodyClick', function() {
console.log('bodyClick received ...');
console.log($rootScope.$$listener);
console.log($rootScope.$$listenerCount);
vs.searchPopoverDisplay = false;
var unbind = $rootScope.$on('popoverOpen', []);
vs.$on('$destroy', unbind);
// $rootScope.$$listenerCount.bodyClick=[];
});
答案 0 :(得分:3)
关于你的傻瓜的几点说明:
$destroy
。 $destroy
但正在尝试
发出destroy
,它不是一样的。从中删除$
听众,你会看到回调正在运行。subController
是mainController
的孩子,所以摧毁主要人员会破坏两者并停止按钮,以及其他所有内容。此行为显示在this plunkr。因此,为了让伪 - $destroy
能够ping,我将其更改为只监听destroy
。
然后,我没有打电话给你的unbind,因为我们实际上并没有$destroy
任何事情,因此我无法在这种情况下工作,我只是替换了bodyClick
函数,因为它绑定到<body>
。
$scope.$on('destroy', function() {
$scope.bodyClick = angular.noop();
});
这似乎有预期的效果。 已更新 Plunkr here。
更新:我发现为什么它会无限期地添加听众......! destroy
侦听器 in 按钮回调。所以按下每个按钮会添加另一个回调。我将destroy
侦听器移到popover
侦听器之外。没有更多的内存泄漏!