简体   繁体   English

从AngularJS服务中销毁事件侦听器

[英]Destroy event listeners from AngularJS service

I wrote this factory: 我写了这个工厂:

function myEvents($log, $rootScope) {
    var service = {
        broadcast: broadcast,
        on: on
    };

    return service;

    function broadcast(name, args) {
        $log.debug('broadcast event: ' + name);
        $rootScope.$broadcast(name, args);
    }

    function on(name, callback) {
        var listener = $rootScope.$on(name, function(event, args) {
            $log.debug('on event: ' + name);
            callback(event, args);
        });
    }
}

to use everytime I need to broadcast an event... this also gave me the chance to log each $on and $broadcast event in my code. 每次我需要播放一个事件时使用...这也让我有机会在我的代码中记录每个$on$broadcast事件。 The problem now is that I don't know how can I access the $scope.$on('$destroy') to unregister my $rootScope listeners. 现在的问题是我不知道怎样才能访问$scope.$on('$destroy')取消注册我的$rootScope监听器。

Does anyone have any advice about it? 有没有人对此有任何建议?

I struggled with this last week and came up with a good solution, I guess. 我猜想,上周我一直在挣扎,想出了一个很好的解决方案。 Based on this blog post , the idea is to create a service, just as you did, to centralize event handling in the application, ie, remove listeners and expose all event names. 基于此博客文章 ,我们的想法是创建一个服务,就像您一样,在应用程序中集中事件处理,即删除侦听器并公开所有事件名称。 I also check event names to warn against typos when publishing or subscribing to an event. 我还检查事件名称,以便在发布或订阅活动时警告拼写错误。

(function() {
'use strict';

angular
    .module('app')
    .factory('eventService', eventService)

eventService.$inject = ['$rootScope', '$log'];


function eventService($rootScope, $log) {

    return {
        subscribe: subscribe,
        publish: publish,
        LOGIN: 'login',
        LOGOUT: 'logout'
    }

    function subscribe(scope, event, callback) {
        safeCheck(this, event);
        var handler = $rootScope.$on(event, callback);
        scope.$on('$destroy', handler);
        return handler;
    }

    function publish(event, data) {
        safeCheck(this, event);
        $rootScope.$emit(event, data);
    }

    function safeCheck(serviceObject, event) {
        var safe = false;
        angular.forEach(serviceObject, function(value, key) {
            if(event == value) {
                safe = true;
            }
        });
        if(!safe) {
            $log.warn("Event " + event + " not found in service");
        }
    }

}


})();

Then you can call the service to subscribe to or publish data into an event, eg, 然后,您可以调用服务来订阅或将数据发布到事件中,例如,

eventService.publish(eventService.LOGIN, userObject);

eventService.subscribe($scope, eventService.LOGIN, function(event, userObject) {

            $log.info("User logged in", userObject);

        });

To answer directly, a solution to your problem could be to pass the $scope to your on method. 要直接回答,问题的解决方案可能是将$scope传递给您的on方法。

Instead of your service, better to use decorator something like this: 而不是你的服务,更好地使用装饰这样的东西:

 angular.module('app').config(['$provide', function ($provide) {
                  $provide.decorator('$rootScope', function ($delegate) {
                      var _emit = $delegate.$emit;
                      var _broadcast = $delegate.$broadcast;
                      var _on = $delegate.$on;

                      $delegate.$emit = function () {
                          $log.debug('emit', arguments);
                          return _emit.apply(this, arguments);
                      };

                      $delegate.$broadcast = function () {
                          $log.debug('broadcast', arguments);
                          return _broadcast.apply(this, arguments);
                      };
                      $delegate.$on = function () {
                          $log.debug('on', arguments);
                          return _on.apply(this, arguments);
                      };
                      return $delegate;
                  });
              }]);

and in your own code as usual $rootScope.$broadcast, $scope.$on and etc. it will decorate all functions in your app, and you can see also third party event, like from ui-router and other libraries 和你自己的代码一样$ rootScope。$ broadcast,$ scope。$ on等等它将装饰你应用程序中的所有功能,你也可以看到第三方事件,比如来自ui-router和其他库

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM