[英]Angular 12 APP_INITIALIZER not firing before other modules
我知道這是一個經常重復的問題,我已經閱讀了幾乎所有的問題,因為我一直試圖讓 app_initializer 啟動好幾個小時,但無濟於事。 所以最后的手段是這個
我想要做的就是動態加載我的 spring 啟動應用程序的 rest 端點,以便我可以部署到多個環境。
我的設置如下:
應用配置服務
.....
loadConfig() : Promise<any> {
const jsonFile = 'assets/config/config.json';
return this.httpClient
.get(jsonFile)
.pipe(tap((result) =>{
AppConfigService.settings = <IAppConfig>result;
console.log(AppConfigService.getConfig());
})).toPromise();
}
應用模塊
export function initializeConfigData(appConfigService: AppConfigService) {
return (): Promise<any> => {
console.log("in app init fn");
return appConfigService.loadConfig2();
}
}
...
providers: [AppConfigService,
{
provide: APP_INITIALIZER, useFactory: initializeConfigData, deps: [AppConfigService], multi: true
}]
發生的事情是我的應用程序中有多個模塊。 例如,auth 模塊有一項服務可以對 rest 端點進行身份驗證調用,並且似乎甚至在應用程序初始化程序完成之前就已啟動。
所以在我加載應用程序后我最終得到了
Uncaught TypeError: Cannot read property 'root' of undefined
在控制台上(root 是我的配置 json 數據中的關鍵)
我已經閱讀了多篇文章,並且在我的 loadConfig 方法中嘗試了很多事情,比如嘗試返回一個新的 Promise((resolve, reject) =>.... 但沒有任何幫助。因為我在 12 歲,所以我也嘗試了 Observables 但沒有任何效果。無論我做什么,我的 AuthenticationService 都會失敗,說明它無法讀取該屬性。
我錯過了什么? 或者這是當您有多個模塊時嘗試讓 app_initializer 工作時的行為。
只是為了測試一下,我嘗試了一個簡單的 setTimeout(沒有用於獲取 URL 的讀取配置)並且按預期觸發了。 所以這該死的東西着火了,但我認為這是時間問題.....我已經無能為力了,所以任何幫助都將不勝感激。
謝謝!
我測試了上面的場景(使用提供的代碼),看起來一切正常(我沒有多個模塊,只有應用程序模塊)。 我在AppComponent.ngOnInit
中記錄配置,它總是有配置值。 N. 盡管如此,我想提出另一種方法。 您可以使用Observable
,而不是在AppConfigService
上寫入和讀取 static 屬性。 這樣所有其他依賴於配置的東西都會等到它在那里。
@Injectable({
providedIn: 'root',
})
export class AppConfigService {
private configSource = new ReplaySubject<IAppConfig>(1);
// public static config: IAppConfig | null = null;
public config$: Observable<IAppConfig> = this.configSource.asObservable();
constructor(private http: HttpClient) {}
loadConfig = (): Observable<any> => {
const jsonFile = 'assets/config/config.json';
return this.http.get(jsonFile).pipe(
tap((result) => {
// AppConfigService.config = result;
this.configSource.next(result);
})
);
};
}
AppModule 看起來與您所擁有的幾乎相同(除了我沒有在 providers 數組中添加AppConfigService
,因為它已經在providedIn: 'root'
中添加):
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializeConfigData,
deps: [AppConfigService],
multi: true,
},
],
每當您需要使用您的配置時,只需注入AppConfigService
並執行您的 http 調用:
@Injectable({
providedIn: 'root',
})
export class AuthService {
constructor(
private appConfigService: AppConfigService,
private http: HttpClient
) {}
getUser(): Observable<any> {
return this.appConfigService.config$.pipe(
switchMap((config) => this.http.get(`${config.root.backendUrl}/users`))
// ...
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.