AngularJS两个不同的$注射器
今天我发现,注入配置或提供程序的AngularJS两个不同的$注射器,angularjs,dependency-injection,angularjs-injector,Angularjs,Dependency Injection,Angularjs Injector,今天我发现,注入配置或提供程序的$injector与注入服务、工厂或控制器的$injector不同 这个$injectors的get()函数的工作原理不同 $injector来自配置或提供程序,无法获取()任何服务$injector.get('myService')抛出错误:[$injector:unpr]未知提供程序:myService,但$injector.has('myService')返回true。这很奇怪 $injector来自维修或控制器,工作正常 以下是一个代码示例,以便于更好地理
$injector
与注入服务、工厂或控制器的$injector
不同
这个$injectors的get()
函数的工作原理不同
$injector
来自配置或提供程序,无法获取()
任何服务$injector.get('myService')
抛出错误:[$injector:unpr]未知提供程序:myService
,但$injector.has('myService')
返回true。这很奇怪
$injector
来自维修或控制器,工作正常
以下是一个代码示例,以便于更好地理解:
angular.module('app', [])
.provider('myProvider', function ($injector) {
this.$get = ['$injector', function (serviceInjector) {
return {
providerInjector: $injector,
serviceInjector: serviceInjector
};
}];
})
.service('myService', function () {})
.controller('myCtrl', function ($scope, myProvider) {
var providerInjector = myProvider.providerInjector;
var serviceInjector = myProvider.serviceInjector;
console.log(providerInjector === serviceInjector); // -> false
console.log(serviceInjector.has('myService')); // `serviceInjector` has `myService`
console.log(getMyService(serviceInjector)); // `serviceInjector` can get `myService`
console.log(providerInjector.has('myService')); // `providerInjector` has `myService` too!
console.log(getMyService(providerInjector)); // but `providerInjector` can't get `myService`! =(
function getMyService(injector) {
try {
injector.get('myService');
return "OK";
} catch (e) {
return e.toString();
}
}
});
有人能解释为什么有两个不同的喷油器吗
我如何使用provider/config中的$injector来注入服务(当然是在服务初始化之后)
请注意,我使用角度1.3.13确定。在阅读了你的评论之后,以下是我的答案 我在plunk中编辑了代码以使其正常工作,在调用providerInjector.get()时,代码应如下所示:
$scope.getMyServiceFromProviderInjector = function () {
try {
myProvider.providerInjector.get('myServiceProvider');//here is change in provider name
return "OK";
} catch (e) {
return e.toString();
}
};
根据以下内容,为配置和运行块引用:
- 配置块-在提供程序注册和配置阶段执行。仅提供程序和常量 可以注入到配置块中。这是为了防止 在服务完全启动之前意外实例化服务 配置
- 运行块-在创建注入器并用于启动应用程序后执行。只能使用实例和常量 注入运行块。这是为了防止进一步的系统故障 在应用程序运行时进行配置
这仅仅意味着,您无法在配置块内获取服务实例。我在github上发现了这个问题: 在配置函数中,$injector是提供者注入器,而在运行函数中,$injector是实例注入器 一个是配置阶段的$injector(只能访问提供程序和常量),另一个是运行阶段的$injector。令人困惑的是,您可能认为$injector在从配置到运行的过程中会修改自身以包含新内容,但事实并非如此。它们是两个独立(尽管相关)的对象,具有各自的实例缓存 这种二分法的一个更深入的原因可能来自对$injector内部结构的深入了解,但它似乎已经非常核心了,两种类型的注入器几乎都有相同的行为,除了它们如何处理实例缓存中的“缓存未命中” 我们将在v2中检修喷油器,因此这将在那里得到修复(摆脱配置阶段是喷油器v2的目标之一)
看起来确实有两个不同的注入器,angular开发人员不会修复这种行为(在版本中,我不久前写了这篇文章,这解释了AngularJS的两个注入器的生命周期,即providerInjector和instanceInjector)
你的问题有点不清楚。你想在provider/config中实现什么?你能给出一个用例吗?用例?例如:在config部分通过$injector获取服务。当然,在服务初始化之后。在我的例子中(显示起来非常复杂)我在配置部分向提供程序添加回调。在回调中,我想使用我的服务。我无法帮助我,所以我使用$injector。当服务已经初始化时,将从控制器调用此回调。@Harry Burns请检查在plunkermyProvider.providerInjector.get('myServiceProvider')中工作的编辑代码将只返回服务的提供者包装,而不是服务本身。您没有回答我的第一个问题-为什么有两个$injector?有什么区别?以及如何获取“service$injector”在配置块中?那么您不认为这里有两个问题。1.为什么有两个不同的$injector。2.如何在配置中使用$injector。?第二个问题的答案是,您不能在配置块中使用$injector,因为在配置块中无法实例化服务。正如我在上面的回答中提到的。请检查以下内容:
.provider('instanceInjector', function () {
var instanceInjector;
function get() {
return instanceInjector;
}
function exists() {
return !!instanceInjector;
}
angular.extend(this, {
get: get,
exists: exists
});
this.$get = function ($injector) {
instanceInjector = $injector;
return {
get: get,
exists: exists
};
}
})
// We need to inject service somewhere.
// Otherwise $get function will be never executed
.run(['instanceInjector', function(instanceInjector){}])