我正在使用APP_INITIALIZER从json获取配置,并且工作正常。 早些时候,我将身份验证保护作为应用程序的一部分,它过去一直运行良好。
然后,我们将授权逻辑拆分为一个库,如果调用forRoot()或为配置提供静态值但允许进行动态配置,则可以很好地工作,我使用库中的InjectionToken来提供配置,而无需调用forRoot。
app.module.ts 的代码如下:
Gen.update
现在 authConfigFactory 在 appInitializerFn 之前被调用,导致未定义,如果我在 authConfigFactory 中添加 async 阻止return语句直到其定义,然后将空值提供给AuthGuard,从而导致无效的令牌URL。
如果我在要求promise之前在 appInitializerFn 中手动提供值,则这些值将被转换并且一切正常。但是在那个阶段还没有动态值。
app-config.service.ts 的代码:
let authConfig: any;
export function authConfigFactory() {
return authConfig;
}
export function appInitializerFn(appConfigService: AppConfigService) {
return () => {
return appConfigService.loadAppConfig().then(() => {
authConfig = {
clientId: appConfigService.getConfig().CLIENT_ID,
tokenEndpoint: appConfigService.getConfig().TOKEN_URL,
redirectURL: "http://localhost",
};
});
};
};
@NgModule({
.....
imports: [
..
AuthLib
],
providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: appInitializerFn,
multi: true,
deps: [AppConfigService]
},
AuthLibService,
{
provide: 'authConfig',
useFactory: authConfigFactory,
deps: []
},
.....
]
bootstrap: [AppComponent]
})
export class AppModule { }
要使这项工作有效的库或代码中缺少什么?
我对Angular政权有些陌生,即使我犯了一些愚蠢的错误,也要让我知道。
答案 0 :(得分:0)
因此找到了原因和解决方法。将其发布给任何人都会绊到这个问题。
由于APP_INITIALIZER被正确调用。我错过的事情是我使用“ HttpClient”来获取配置,而该配置又调用了ROOT中定义的任何HTTP_INTERCEPTORS,并最终导致了Authentication Service的初始化,而后者又需要auth config作为构造函数中的令牌注入。
因此,即使在获取值之前也会注入令牌,从而导致令牌变为未定义/空。
解决方案虽然很简单,但我们可以使用
在我的情况下,第3点是不可能的,因为我想对所有通信进行严格控制,而第2点有点笨拙。我们采用了方法1.共享修改后的代码以供参考。
import { Injectable } from '@angular/core';
import { HttpClient, HttpBackend } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { AppConfig } from '../_models/app-config';
import { LoggingService } from './logging.service';
@Injectable()
export class AppConfigService {
static appConfig : AppConfig;
private dataLoc: string;
constructor(private handler: HttpBackend,
private logger: LoggingService) { }
loadAppConfig() {
if(environment.production){
this.dataLoc = '/assets/data/appConfig.json';
}
else{
this.dataLoc = '/assets/data/appConfig-dev.json';
}
return new HttpClient(this.handler).get(this.dataLoc)
.toPromise()
.then((data:AppConfig) => {
this.logger.info(data);
AppConfigService.appConfig = data;
});
}
getConfig() {
return AppConfigService.appConfig;
}
}
由于@ysf,您的最小示例使我想到,如果它在一般情况下正常工作,则在初始化过程中会调用authconfig。