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

时间:2016-09-08 07:21:30

标签: javascript angularjs angularjs-scope

我写了这个工厂:

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);
        });
    }
}

每次我需要播放一个事件时使用...这也让我有机会在我的代码中记录每个$on$broadcast事件。 现在的问题是我不知道如何访问$scope.$on('$destroy')以取消注册我的$rootScope听众。

有人对此有任何建议吗?

2 个答案:

答案 0 :(得分:2)

上周我挣扎于此,并想出了一个很好的解决方案。基于此built-in filter for this in ansible,我们的想法是创建一个服务,就像您一样,在应用程序中集中事件处理,即删除侦听器并公开所有事件名称。我还检查事件名称,以便在发布或订阅活动时警告拼写错误。

users.php?page=$1

然后,您可以调用该服务来订阅或将数据发布到事件中,例如,

(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");
        }
    }

}


})();

要直接回答,问题的解决方案可能是将eventService.publish(eventService.LOGIN, userObject); eventService.subscribe($scope, eventService.LOGIN, function(event, userObject) { $log.info("User logged in", userObject); }); 传递给您的$scope方法。

答案 1 :(得分:1)

而不是你的服务,更好地使用装饰 像这样的东西:

 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;
                  });
              }]);

和你自己的代码一样$ rootScope。$ broadcast,$ scope。$ on等。 它将装饰你的应用程序中的所有功能,你也可以看到第三方事件,如来自ui-router和其他库