javascript 我应该把所有控制器使用的 AngularJS 中的事件侦听器代码放在哪里?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21451054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 20:56:15  来源:igfitidea点击:

Where do I put event listener code in AngularJS that all controller use?

javascriptangularjsangularjs-scope

提问by jcm

I want to have some event listener code in my AngularJS app which will apply to the scope of all controllers.

我想在我的 AngularJS 应用程序中有一些事件侦听器代码,这些代码将应用于所有控制器的范围。

I basically want to define the following somewhere:

我基本上想在某处定义以下内容:

    document.addEventListener("online", onOnline, false);
    document.addEventListener("offline", onOffline, false);

    function onOnline() {
        console.log("just got online event");
        $scope.noNetwork = false;
    }

    function onOffline() {
        console.log("just got offline event");
        $scope.noNetwork = true;
    }

which will receive events no matter which controller scope is currently active.

无论哪个控制器范围当前处于活动状态,它都会接收事件。

采纳答案by Khanh TO

Try $rootScope:

尝试$rootScope

var app = angular.module("yourModule",[]);
app.run(function($rootScope){
   document.addEventListener("online", onOnline, false);
   document.addEventListener("offline", onOffline, false);

   function onOnline() {
        $rootScope.$apply(function(){
            console.log("just got online event");
            $rootScope.noNetwork = false;
        });
    }

    function onOffline() {
        $rootScope.$apply(function(){
             console.log("just got offline event");
             $rootScope.noNetwork = true;
        });
    }
});

Due to scope inheritance, $rootScope's properties will be inherited by all your child scopes. Be aware that this event occurs outside angular, the use of $applyis also necessary in this case. All your child scopes can $watch noNetworkchanges. Like this:

由于作用域继承,$rootScope 的属性将被您所有的子作用域继承。请注意,此事件发生在 angular 之外,$apply在这种情况下也需要使用。你所有的子作用域都可以 $watchnoNetwork变化。像这样:

$scope.$watch('noNetwork',function(newValue){
//Handle your tasks here.
});

Another option is creating a service to hold the noNetworkproperty and inject that service into your controllers.

另一种选择是创建一个服务来保存noNetwork属性并将该服务注入到您的控制器中。

回答by vp_arth

Just to expand @KhanhTo's Another optionrow:

只是为了扩展@KhanhTo 的Another option行:

;(function initModule(module) {

  module.provider('IsOnlineService', Provider);
  function Provider() {
    var eventNames = {
      online: 'online', 
      offline: 'offline'
    };
    this.setOnlineEventName = function(name) {eventNames.online = name;}
    this.setOfflineEventName = function(name) {eventNames.offline = name;}
    this.$get = OnlineService;

    OnlineService.$inject = ['$document', '$rootScope'];
    function OnlineService($document, $rootScope) {
      // Listen events
      $document.addEventListener(eventNames.online, setState.bind(this, true), false);
      $document.addEventListener(eventNames.offline, setState.bind(this, false), false);

      // Observer pattern: everybody can receive updates
      var subscribers = {};
      this.subscribe = subscribe;
      this.unsubscribe = unsubscribe;

      var state = false;
      this.getState = getState;

      return this;

      // Implementation
      function subscribe(id, sub) {subscribers[id] = sub;}
      function unsubscribe(id) {delete subscribers[id];}
      function announceAll(value) {
        Object.keys(subscribers, function(id){
          subscribers[id](value);
        });
      }

      function getState() {return state;}
      function setState(value) {
        state = value;
        $rootScope.$apply(announceAll.bind(null, state));
      }
    }
  }

})(angular.module('yourModule', [
]));

Configuration:

配置:

angular.module('app')
.config(['IsOnlineServiceProvider', function(online){
  online.setOfflineEventName('away');
}]);

Usage:

用法:

angular.module('app')
.controller('SomeCtrlr', ['IsOnlineService', function(online){
  // Direct way:
  this.online = online.getState();
  this.isOnline = online.getState;
  // SubPub: 
  online.subscribe('somectrlr', function(state){
    this.isOnline = state;
    this.onlineStr = state ? 'Online' : 'Offline';
  });
}]);

回答by TestersGonnaTest

You could add this in your top controller and your child controllers would see the value for $scope.noNetwork

您可以将它添加到您的顶级控制器中,您的子控制器将看到 $scope.noNetwork 的值