Angular 1:在提供程序中注入提供程序时,$ injector无法找到提供程序依赖项

时间:2017-02-03 19:09:59

标签: angularjs dependency-injection

我的用例是:我们有几个辅助类,A和B,它们是服务,A依赖于B,我想让它们成为提供者,以便它们可以在.config阶段使用。

我跟着this SO answer加载了提供商内的提供商。

正如你在这里看到的,它有效:

http://plnkr.co/edit/SIvujHt7bprFumhxwJqD?p=preview

var coreModule = angular.module('CoreModule', []);
coreModule.provider('Car', function() {
  //CarProvider.engine
  this.engine = 'big engine';

  //Car
  this.$get = function() {
    return {
      color: 'red'
    };
  };
});
coreModule.provider('ParameterService', ['$injector', function($injector) {
  try {
    var CarProvider = $injector.get('CarProvider');
    this.deepEngine = CarProvider.engine;
    console.log('deepEngine = ' + this.deepEngine);
  } catch (e) {
    console.log("nope!")
  }

  // ParameterService
  this.$get = function() {
    return {};
  };
}]);
coreModule.config(function(CarProvider) {
  console.log('configEngine = ' + CarProvider.engine); // big engine
});

如果我按此顺序在一个文件中CarParameterService,则此方法有效。

但是,当我将CarParameterService分割到磁盘上的多个文件中,或者我在同一文件中ParameterService之前定义Car时,$injector.get('CarProvider')内{ {1}}失败。

如何解决此问题?

我希望每个文件都有一个提供者/服务,但我不明白缺少什么。

2 个答案:

答案 0 :(得分:2)

在注入服务实例的运行阶段,定义服务的顺序无关紧要。但在注入服务提供者的配置阶段,即在provider构造函数和config块中,它确实很重要。

提供者和配置块按照定义的顺序执行。如果在Car提供程序或ParameterService阻止后定义了config提供程序,则{2}执行时CarProvider不存在。

为避免潜在的竞争条件,应遵循每个文件模式一个模块。这允许保持应用程序高度模块化(也有利于测试),并且从不关心文件的加载顺序。 E.g:

angular.module('app', ['app.carService', 'app.parameterService']).config(...);

angular.module('app.carService', []).provider('Car', ...);

angular.module('app.parameterService', []).provider('ParameterService', ...);

模块部件按照angular.module数组层次结构中定义模块的顺序执行,从子项到父项。

config块是否需要自己的模块的决定取决于它的作用(主要是出于测试原因)。

答案 1 :(得分:1)

可以在不同的文件中包含提供程序。您只需将它们附加到您创建的第一个模块即可。

如果你的标记看起来像这样:

<script src="coreModule.js"></script>
<script src="parameterService.js"></script>

然后,在coreModule.js中,定义您的模块:

angular.module('CoreModule', [])
    .provider('Car', function() {
        ...
    }

请记住,第二个参数([])告诉angular创建一个新模块。

然后,在另一个文件中声明您的其他提供程序,并将其附加到您现有的“CoreModule”模块:

angular.module('CoreModule')
.provider('ParameterService', ['$injector', function($injector) {
    ...
}

请注意,我们只将一个参数传递给.module()。这告诉angular将您的提供者添加到现有模块。

Plunkr Demo

相关问题