是否可以在提供商方法中进行DI?
在这个例子中
angular.module('greet',[])
.provider('greeter',function() {
this.$get=function() {
};
})
.service('greeterService',function($http){
console.log($http);
})
;
将$http
注入服务似乎是正确的实现,但它在提供程序方法中不起作用并且它会引发错误:
未知提供商:$ http
提供者方法是否与DI一起使用以注入服务?
答案 0 :(得分:58)
您当然可以向提供商注入$http
。只需确保它出现在$get
中,而不是函数构造函数中。如下:
angular.module('greet',[]).provider('greeter',function() {
this.$get = function($http) {
};
});
答案 1 :(得分:11)
您可以将常量和其他提供程序注入提供程序。不是服务或工厂 - 有一个例外。您似乎可以将$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
方法之外使用注射器,但在配置时仍然无法从中获取服务。
答案 2 :(得分:6)
跟进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
};
});
答案 3 :(得分:3)
不,您无法将服务注入提供程序本身。 将服务注入提供者的$ get方法与将服务注入工厂相同,但不能直接将其注入提供者函数。
$ get和提供者本身之间的区别在于提供程序在module loading phase期间运行,而$ get在实例化您提供的服务时运行。
这意味着在模块的模块加载/配置阶段,您根本无法使用任何服务。这就是您在配置块中运行的所有内容,例如在定义应用程序路由或状态时,无法使用任何服务。
除了提供程序之外,您可以注入配置块的唯一其他内容是常量。
你可以做一些像IgrCndd建议的事情。但是,如果您需要在配置块中使用提供程序,毕竟这是提供程序的目的,那么您将不会在很久之后注入您的值。所以除非你使用promises做一些令人讨厌的黑客攻击,否则它不会起作用。
答案 4 :(得分:2)
您实际上必须在$ get上注入依赖项,然后将其存储以用于从$ get检索的内容。一点都不漂亮......