Angular 当服务注入到其他地方时提供商配置重置
Angular provider configuration reset when service injected into somewhere else
描述这一点并不容易,但基本上我有一项设置为提供商的服务,因此我可以对其进行配置。它有一个在我的项目中使用的 APIs 数组,最初是空的。各种配置块可以向数组添加一个 API 对象,这似乎是可行的。我每次 console.log 输出并且数组在增长。
然后我将我的服务注入其他东西(在本例中为 $http 拦截器函数)并使用服务方法 return 数组,但每次我得到一个空数组。
我认为它的工作方式是所有配置首先阻塞 运行,然后被拦截的 $http 调用发生,所以数组应该充满 API s 到它被拦截的时候。
无论如何,这是一些代码
angular.module('authModule').provider('authService', function(){
var _apis = [];
return({
addApi: addApi,
$get: instantiateAuth
});
function addApi(newApi){
_apis.push(newApi);
console.log("API added", _apis);
}
function instantiateAuth() {
return({
getApis: function(){
console.log("Getting APIs", _apis);
return _apis;
}
});
}
})
.config(function($httpProvider){
$httpProvider.interceptors.push(function($log, $rootScope, $q) {
return {
request: function(config) {
var injector = angular.injector(['ng', 'authModule']);
var authService = injector.get('authService');
console.log("apis", authService.getApis());
}
};
});
});
以及示例配置块
angular.module('myModule').config(function ($provide, authServiceProvider) {
authServiceProvider.addApi({
url: 'https://apiurl.com',
other: 'stuff'
});
authServiceProvider.addApi({
url: 'https://apiurl2.com',
other: 'stuff'
});
});
因此,每次在配置块中调用 appApi 方法时(此处两次),此行输出数组 console.log("API added", _apis);它在第一次调用后正确输出 1 个项目,在第二次调用后正确输出两个项目。
当此代码 - authService.getApis() - 在第一次拦截 HTTP 调用时触发时,它会将一个空数组记录到控制台。
如有任何帮助,我们将不胜感激。
编辑:
问题似乎出在这一行
var 注入器 = angular.injector(['ng', 'authModule']);
每次发生这种情况时,我的提供商似乎都是 reset/recreated,所以我可能误解了如何使用注射器。我最初只是在函数参数中以正常方式注入我的 authService 但我得到了循环依赖(我的 auth 服务需要打开模态 window,但是 angular-ui 模态依赖在 http 服务上,我的 http 调用被拦截以检查我的 auth 服务用户是否已通过身份验证:( )
是的,angular.injector(['ng', 'authModule'])
本质上是创建一个新的注入器实例(应用程序实例,通俗地说):
angular.injector(['authModule']) !== `angular.injector(['authModule'])
ng
模块默认加载,不必明确指定。单例服务仅在同一个注入器实例中是单例:
injector.get('authService') === injector.get('authService');
但是
angular.injector(['authModule']).get('authService') !== `angular.injector(['authModule']).get('authService')
要重用当前注入器实例(这在几乎所有情况下都是理想的行为)应该使用 $injector
service:
$httpProvider.interceptors.push(function($log, $rootScope, $q, $injector) {
return {
request: function(config) {
var authService = $injector.get('authService');
}
};
});
$injector.get
是解决循环依赖的已知且直接的解决方案。
描述这一点并不容易,但基本上我有一项设置为提供商的服务,因此我可以对其进行配置。它有一个在我的项目中使用的 APIs 数组,最初是空的。各种配置块可以向数组添加一个 API 对象,这似乎是可行的。我每次 console.log 输出并且数组在增长。
然后我将我的服务注入其他东西(在本例中为 $http 拦截器函数)并使用服务方法 return 数组,但每次我得到一个空数组。
我认为它的工作方式是所有配置首先阻塞 运行,然后被拦截的 $http 调用发生,所以数组应该充满 API s 到它被拦截的时候。
无论如何,这是一些代码
angular.module('authModule').provider('authService', function(){
var _apis = [];
return({
addApi: addApi,
$get: instantiateAuth
});
function addApi(newApi){
_apis.push(newApi);
console.log("API added", _apis);
}
function instantiateAuth() {
return({
getApis: function(){
console.log("Getting APIs", _apis);
return _apis;
}
});
}
})
.config(function($httpProvider){
$httpProvider.interceptors.push(function($log, $rootScope, $q) {
return {
request: function(config) {
var injector = angular.injector(['ng', 'authModule']);
var authService = injector.get('authService');
console.log("apis", authService.getApis());
}
};
});
});
以及示例配置块
angular.module('myModule').config(function ($provide, authServiceProvider) {
authServiceProvider.addApi({
url: 'https://apiurl.com',
other: 'stuff'
});
authServiceProvider.addApi({
url: 'https://apiurl2.com',
other: 'stuff'
});
});
因此,每次在配置块中调用 appApi 方法时(此处两次),此行输出数组 console.log("API added", _apis);它在第一次调用后正确输出 1 个项目,在第二次调用后正确输出两个项目。
当此代码 - authService.getApis() - 在第一次拦截 HTTP 调用时触发时,它会将一个空数组记录到控制台。
如有任何帮助,我们将不胜感激。
编辑:
问题似乎出在这一行
var 注入器 = angular.injector(['ng', 'authModule']);
每次发生这种情况时,我的提供商似乎都是 reset/recreated,所以我可能误解了如何使用注射器。我最初只是在函数参数中以正常方式注入我的 authService 但我得到了循环依赖(我的 auth 服务需要打开模态 window,但是 angular-ui 模态依赖在 http 服务上,我的 http 调用被拦截以检查我的 auth 服务用户是否已通过身份验证:( )
是的,angular.injector(['ng', 'authModule'])
本质上是创建一个新的注入器实例(应用程序实例,通俗地说):
angular.injector(['authModule']) !== `angular.injector(['authModule'])
ng
模块默认加载,不必明确指定。单例服务仅在同一个注入器实例中是单例:
injector.get('authService') === injector.get('authService');
但是
angular.injector(['authModule']).get('authService') !== `angular.injector(['authModule']).get('authService')
要重用当前注入器实例(这在几乎所有情况下都是理想的行为)应该使用 $injector
service:
$httpProvider.interceptors.push(function($log, $rootScope, $q, $injector) {
return {
request: function(config) {
var authService = $injector.get('authService');
}
};
});
$injector.get
是解决循环依赖的已知且直接的解决方案。