Javascript 如何在AngularJS中销毁$emit和$broadcast事件?
Plnkr示例构建: ,我创建了一些Javascript 如何在AngularJS中销毁$emit和$broadcast事件?,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,Plnkr示例构建: ,我创建了一些$broadcast事件,以允许主$scope中的操作关闭子$scopes中的弹出窗口。然而,我想确保我清理了我所有的活动,没有任何不应该拖延的事情 我有一个popover指令,一旦popover被激活,我会发出: vs.$emit('popoverOpen'); 然后在主应用程序模块($rootScope)中,我在这里收听它: vs.$on('popoverOpen',function(events,data) { // if 'popoverO
$broadcast
事件,以允许主$scope
中的操作关闭子$scopes
中的弹出窗口。然而,我想确保我清理了我所有的活动,没有任何不应该拖延的事情
我有一个popover指令,一旦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
listener:
vs.$on('bodyClick', function() {
vs.searchPopoverDisplay = false;
$rootScope.$$listenerCount.bodyClick=[];
});
^我也有代码试图杀死bodyClick
事件,但是没有用:(
正如您在下面看到的,我已经从$$listenerCount
对象中删除了bodyClick
和popoverOpen
(在$$listener
对象中没有任何内容)
但是,用户仍然能够访问主应用程序根范围中的vs.bodyClick()
功能,即使popoverOpen
应该已被删除
第一次加载时也是如此:
- 如果用户在没有打开任何popover的情况下四处点击,
将永远不会被捕获/传输bodyClick
- 打开弹出框后,
处于活动状态bodyClick
- 如果用户单击主体,则发送该事件并关闭弹出窗口
- 但是,现在即使没有打开弹出窗口,如果用户单击正文,则
事件仍会被发送出去bodyClick
在发送
body click
事件以关闭popover后,如何正确删除事件
更新 我也尝试过这个(),但是bodyClick事件仍然会在popover关闭并被销毁后被发送出去 popoverDirective函数仍被调用:
关于您的PRUNKR的几点注意事项:
$destroy
$destroy
,但正在尝试
发出destroy
,这是不同的。请从中删除$
侦听器,您将看到回调正在运行subcroller
是main控制器的子控制器
销毁main会同时销毁和停止按钮以及其他所有内容。此行为如中所示$destroy
转换为ping,我将其更改为只监听destroy
然后,我没有调用unbind(在本例中不起作用,因为我们实际上没有销毁任何东西),而是简单地替换了bodyClick
函数,因为它绑定到
这似乎达到了预期效果。已更新
更新:我发现了它无限期添加侦听器的原因…!按钮回调中有
销毁
侦听器。因此每次按下按钮都会添加另一个回调。我将销毁
侦听器移到popover
侦听器之外。不再有内存泄漏!托德格言的提到销毁发布和订阅事件的ngular指南。这可能是您正在寻找的。谢谢!嗯,我尝试了他的destroy
代码,但不起作用。还必须修复那里的语法错误,但仍然没有运气…添加了我在上面尝试过的内容。现在构建一个plnkr示例,因此,我为您的$destroy
列表添加了一个控制台然后我添加了一个$scope.$destroy()
在你的身体点击后,点击调用,噗!没有更多的警报。不确定它是否有预期的后效…哦,这就是我想做的,你如何真正破坏作用域?感谢第一部分。我想阻止调用某个函数,但我也不想在事件不存在时再调用它们eded.Simply:$scope.$destroy()是的,我一直在仔细考虑这个plunkr。我认为它的结构使得给你一个可靠的答案变得非常困难。例如,你在我们试图解除绑定的回调函数中设置了一个$scope
函数,它实际上不会解除该变量的绑定,所以该方法仍然存在。希望这能把你推向正确的方向方向。谢谢,是的,现在我正在查看你的plnkr,当用户单击按钮时,警报永远不会回来。警报只会发生一次,但每次单击按钮时都会发出警报,只是不会在身体的其他部位发出警报。我会玩这个…谢谢!@LeonGaban我在plunkr中发现了主要问题。我更新了链接。问题是我们在按按钮的回叫声中听着我们的破坏声!
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=[];
});
$scope.$on('destroy', function() {
$scope.bodyClick = angular.noop();
});