簡體   English   中英

Angular 12 APP_INITIALIZER 未在其他模塊之前觸發

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM