AngularJS-一种无需调用即可具有许多服务依赖关系的干净方法

时间:2019-03-07 22:51:11

标签: angularjs angularjs-service

我有一个服务,需要在加载约10个其他服务(“ B”-“ L”)之后再加载(“ A”),因为其他10个服务在启动时都会调用,而“ A”需要每个被调用。

我知道我能做的是

var module = angular.module('AModule',[]); 

module.service('A', ['B', 'C', 'D',...'L', function() {
     //A's functionality
    }
]);

但是,在A中,我从未显式调用任何其他服务的方法,并且从未见过这样的模式:声明服务依赖于其他服务,而这些服务实际上并未注入/使用。有更好的方法吗?

我想做的是

var module = angular.module('AModule',[
     BThroughLModule
]);

其中BThroughLModule通过L服务注册B。但这不起作用-声明模块依赖性并不能保证在A模块之前实例化这些模块的服务。

2 个答案:

答案 0 :(得分:0)

您可以在控制器中使用$watchGroup来检查是否将所有B ... L服务的isLoaded属性设置为true,并且仅当所有这些服务都将该属性设置为如果为true,则在服务A中运行一个函数以加载它。请参阅下面的示例。

angular
  .module('app', [])
  .controller('myController', function($scope, A, B, C) {
    $scope.A = A;
    $scope.B = B;
    $scope.C = C;

    var watchGroup = [
      'B.isLoaded',
      'C.isLoaded'
    ];

    $scope.$watchGroup(watchGroup, function(watchGroup) {
      for (var i = 0; i < watchGroup.length; i++) {
        if (!watchGroup[1]) {
          return;
        }
      }
      A.loadService();
    });
  })
  .factory('A', function($timeout) {
    var service = {
      isLoaded: false,
      loadService: loadService
    };

    function loadService() {
      $timeout(function() { //simulate api call
        service.isLoaded = true;
      }, 1000)
    }

    return service;
  })
  .factory('B', function($timeout) {
    var service = {
      isLoaded: false
    };

    $timeout(function() { //simulate api call
      service.isLoaded = true;
    }, 3000)


    return service;
  })
  .factory('C', function($timeout) {
    var service = {
      isLoaded: false
    };

    $timeout(function() { //simulate api call
      service.isLoaded = true;
    }, 5000)

    return service;
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="myController">
  <div>Service A is loaded (when B and C are loaded): {{A.isLoaded}}</div>
  <div>Service B is loaded: {{B.isLoaded}}</div>
  <div>Service C is loaded: {{C.isLoaded}}</div>

</div>

答案 1 :(得分:0)

您可以执行以下操作,而不是单个服务本身对其实例进行调用。

在所有服务上公开一个init方法。然后,创建一个服务模块,并将所有服务注入module.run()块中,并调用所有服务初始化方法。这样,它就更清洁了,您不必跟踪服务是否已加载。然后,您可以将服务模块作为依赖项添加到主模块。

angular.module('Services.Init', [])
       .run(['A','B','C', 'D', function(A, B, C, D){
            A.init();
            B.init();
            C.init();
            D.init();
        });

angular.module('Main', ['Services.Init']);