2016-09-08 9 views
1

からイベントリスナーを破壊:...私はこの工場を書いたAngularJSサービス

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リスナーを登録解除するにはどうすればよいかわかりません。

誰かに助言がありますか?代わりに、あなたのサービスの

答えて

1

、このような何かデコレータ を使用して、より良い:。通常の$ rootScopeとして

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

と独自のコードで$放送、$スコープ$ 上となど、それは飾るます。あなたのアプリのすべての機能、そしてあなたもui-routerや他のライブラリのようなサードパーティのイベントを見ることができます。

1

私はこの先週に苦労し、良い解決策を思いつきました。このblog postに基づいて、アプリケーションのイベント処理を集中管理する、つまりリスナーを削除してすべてのイベント名を公開するというサービスを作成することが考えられます。また、イベントを公開または購読する際に、誤植を警告するためにイベント名をチェックします。

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

     }); 

、例えば、イベントにデータをを購読するか、パブリッシュするサービスを呼び出すことができ、あなたの問題を解決するには、あなたのon$scopeを渡すことができ方法。

関連する問題