如何在 AngularJS 中取消注册到 rootscope 的广播事件? [英] How can I unregister a broadcast event to rootscope in AngularJS?

查看:31
本文介绍了如何在 AngularJS 中取消注册到 rootscope 的广播事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下几点:

angular.module('test').controller('QuestionsStatusController1',['$rootScope', '$scope', '$resource', '$state',函数($rootScope,$scope,$resource,$state){$scope.action2 = function() {$rootScope.$broadcast('action2@QuestionStatusController1');}}]);angular.module('测试').controller('QuestionsStatusController2',['$rootScope', '$scope', '$resource', '$state',函数($rootScope,$scope,$resource,$state){$rootScope.$on('action2@QuestionStatusController1', function {//在这里写你的听众})}]);

据我所知,我需要取消注册监听事件.有人可以告诉我如何编码/执行此操作吗?

解决方案

如果你不注销事件,你会得到内存泄漏,作为你传递给 $on 的函数不会被清理(因为它的引用仍然存在).更重要的是,函数在其范围内引用的任何变量也将被泄漏.如果您的控制器在应用程序中被多次创建/销毁,这将导致您的函数被多次调用.幸运的是,AngularJS 提供了一些有用的方法来避免内存泄漏和不需要的行为:

  • $on 方法返回一个函数,可以调用该函数来取消注册事件侦听器.您需要将取消注册函数保存为变量以备后用: var cleanUpFunc = $scope.$on('yourevent', ...); 请参阅 $ 的文档: http://docs.angularjs.org/api/ng.$ro​​otScope.Scope#$on

  • 每当 Angular 中的作用域被清理(即控制器被销毁)时,就会在该作用域上触发 $destroy 事件.您可以注册到 $scope$destroy 事件并从中调用您的 cleanUpFunc.

您可以将这两个有用的东西联系在一起,以正确清理您的订阅.我整理了一个这样的例子:http://plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview.如果您注释掉 cleanUpFunc(); 行,然后点击切换和执行按钮几次,您会注意到我们的事件处理程序被多次调用,这并不是真正需要的.>

现在,为了使您的特定情况正确运行,只需将 QuestionsStatusController2 中的代码更改为以下内容:

angular.module('test').controller('QuestionsStatusController2',['$rootScope', '$scope', '$resource', '$state',函数($rootScope,$scope,$resource,$state){var cleanUpFunc = $rootScope.$on('action2@QuestionStatusController1', function {//在这里写你的听众});$scope.$on('$destroy', function() {cleanUpFunc();});}]);

通过在 $destroy 中调用 cleanUpFunc(),您的 action2@QuestionStatusController1 事件监听器将被取消订阅,您将当您的控制器被清理时不再泄漏内存.

I have the following:

angular.module('test')
    .controller('QuestionsStatusController1',
    ['$rootScope', '$scope', '$resource', '$state',
    function ($rootScope, $scope, $resource, $state) {

        $scope.action2 = function() {
            $rootScope.$broadcast('action2@QuestionStatusController1');
        }

    }]);

angular.module('test')
   .controller('QuestionsStatusController2',
   ['$rootScope', '$scope', '$resource', '$state',
   function ($rootScope, $scope, $resource, $state) {

    $rootScope.$on('action2@QuestionStatusController1', function {
         //write your listener here
    })

   }]);

It's my understanding that I need to unregister the listening event. Can someone tell me how I could code / do this?

解决方案

If you don't un-register the event, you will get a memory leak, as the function you pass to $on will not get cleaned up (as a reference to it still exists). More importantly, any variables that function references in its scope will also be leaked. This will cause your function to get called multiple times if your controller gets created/destroyed multiple times in an application. Fortunately, AngularJS provides a couple of useful methods to avoid memory leaks and unwanted behavior:

  • The $on method returns a function which can be called to un-register the event listener. You will want to save your de-register function as a variable for later use: var cleanUpFunc = $scope.$on('yourevent', ...); See the documentation for $on: http://docs.angularjs.org/api/ng.$rootScope.Scope#$on

  • Whenever a scope gets cleaned up in Angular (i.e. a controller gets destroyed) a $destroy event is fired on that scope. You can register to $scope's $destroy event and call your cleanUpFunc from that.

You can tie these two helpful things together to clean up your subscriptions properly. I put together an example of this: http://plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview. If you comment out the line cleanUpFunc(); and then hit the toggle and do stuff button a few times, you will notice that our event handler gets called multiple times, which is not really desired.

Now, after all of that, to make your specific situation behave correctly, just change your code in QuestionsStatusController2 to the following:

angular.module('test')
   .controller('QuestionsStatusController2',
   ['$rootScope', '$scope', '$resource', '$state',
   function ($rootScope, $scope, $resource, $state) {

    var cleanUpFunc = $rootScope.$on('action2@QuestionStatusController1', function {
         //write your listener here
    });

    $scope.$on('$destroy', function() {
        cleanUpFunc();
    });

   }]);

By calling cleanUpFunc() in $destroy, your event listener for the action2@QuestionStatusController1 event will be un-subscribed and you will no longer be leaking memory when your controller gets cleaned up.

这篇关于如何在 AngularJS 中取消注册到 rootscope 的广播事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆