Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在AngularJS中销毁$emit和$broadcast事件?_Javascript_Angularjs_Angularjs Directive_Angularjs Scope - Fatal编程技术网

Javascript 如何在AngularJS中销毁$emit和$broadcast事件?

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

Plnkr示例构建:

,我创建了一些
$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();
    });