33

是否可以在提供者方法中进行 DI?

在这个例子中

angular.module('greet',[])
.provider('greeter',function() {

  this.$get=function() {

  };
})
.service('greeterService',function($http){
  console.log($http);
})
;

注入$http服务似乎是正确的实现,但它在提供程序方法中不起作用并且会引发错误:

未知提供者:$http

提供者方法是否与 DI 一起使用以注入服务?

4

5 回答 5

58

您当然可以注入$http提供者。只要确保它出现在 中$get,而不是函数构造函数中。如下:

angular.module('greet',[]).provider('greeter',function() {
  this.$get = function($http) {

  };
});
于 2013-10-04T02:44:04.910 回答
13

您可以将常量和其他提供程序注入提供程序。不是服务或工厂——只有一个例外。似乎您可以将$injector服务注入提供程序 - 至少,您可以在 AngularJS 1.3.16 中。

.provider('foo', ['$injector', function ($injector) {
  var messagePrefix = $injector.get('msgPrefix');
  this.message = '';

  this.$get = function() {
    var that = this;
    return function() {
      return messagePrefix + that.message;
    }
  };
}])

你可以在方法外使用注入器$get,但在配置时仍然无法从中获取服务。

请参阅此处进行演示

于 2015-06-09T23:42:39.080 回答
7

跟进 IgrCndd 的回答,这里有一个模式可以避免潜在的麻烦:

angular.module('greet',[]).provider('greeter', function() {

    var $http;

    function logIt() {
        console.log($http);
    }

    this.$get = ['$http', function(_$http_) {
        $http = _$http_;

        return {
            logIt: logIt
        };
    }];
});

请注意,这与等效服务有多么相似,从而使两者之间的转换变得不那么麻烦:

angular.module('greet',[]).factory('greeter', ['$http', function($http) {

    function logIt() {
        console.log($http);
    }

    return {
        logIt: logIt
    };
});
于 2016-01-07T14:14:55.140 回答
3

不,您不能将服务注入提供程序本身。将服务注入提供者的 $get 方法与将服务注入工厂相同,但不能直接将其注入提供者函数中。

$get 和提供程序本身的区别在于提供程序在模块加载阶段运行,而 $get 在实例化您提供的服务时运行。

这意味着您在模块的模块加载/配置阶段根本无法使用任何服务。这就是您在配置块中运行的所有内容,例如在定义应用程序路由或状态时,不能使用任何服务。

除了提供者之外,您可以注入配置块的唯一其他东西是常量。

您可以执行 IgrCndd 建议的操作。但是,如果您需要在配置块中使用提供程序,这毕竟是提供程序的目的,那么直到很久之后您才会注入您的值。因此,除非您使用 Promise 进行一些令人讨厌的 hack,否则它不会起作用。

进一步阅读注射剂

于 2015-04-28T13:16:02.573 回答
3

您实际上必须注入对 $get 的依赖项,然后将其存储以用于从 $get 检索的内容。一点都不漂亮……

于 2014-04-27T16:01:42.417 回答