appsettings.json 在 APP_INITIALIZER 应用程序初始化后加载文件

appsettings.json file loading after app init on APP_INITIALIZER

我一直在尝试在 DevOps 上部署 Angular 8 应用程序并在 .json 文件中使用配置,以便不重新构建针对不同环境的整个应用程序。

我使用了这两个帖子来创建所有配置:

Continuously Deploying Angular to Azure App Service with Azure DevOps

和堆栈溢出答案:

注意 我对使用 environment.ts 方式不感兴趣,因为这种方式需要我为每个环境重新构建解决方案。

所以,我准备了我所有的代码:

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule
    ],
    providers: [
        {
             provide: APP_INITIALIZER,
             useFactory: (appConfigService: ConfigService) => {
             return () => {
                //Make sure to return a promise!
                return appConfigService.loadAppConfig();
             };
          },
          deps: [ConfigService],
          multi: true
       }
    ],
    bootstrap: [AppComponent]
 })
 export class AppModule {}

我的ConfigService.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ConfigService {
private appConfig: any;

constructor(private http: HttpClient) {}

loadAppConfig() {
  return this.http.get('./assets/appconfig.json')
    .toPromise()
    .then(config => {
      this.appConfig = config;
    });
}

get apiBaseUrl() {
    if (!this.appConfig) {
      throw Error('Config file not loaded!');
    }

    return this.appConfig.apiUrl;
  }
}

然后,需要加载appconfig.json信息的主要对象:

  export class ApiService {
  apiUrl: string;

     constructor(private readonly httpClient: HttpClient,
          private configService: ConfigService) { 
            this.apiUrl = this.configService.apiBaseUrl;
     }

     ngOnInit() {
       this.apiUrl = this.configService.apiBaseUrl;
     }    
  }

但是,在加载应用程序时,会出现此消息:

如果我调试应用程序,appsettings.json 文件正在加载信息,但看起来 angular 初始化在加载应用程序设置之前发生。

我做错了什么?

您可以 return 一个 Promise 并在 HTTP 请求的 subscribe 回调中解析它,如下所示:

loadAppConfig() {
  return new Promise((resolve) => {
     this.http.get('./assets/appconfig.json').subscribe(config => {
        this.appConfig = config;
        resolve();
     })
  });
}

所以除了一件重要的事情外,一切都配置得很好:构造函数仅用于注入依赖项。所以在那个时候,我做不到:

constructor(private readonly httpClient: HttpClient,
      private configService: ConfigService) { 
        this.apiUrl = this.configService.apiBaseUrl;
 }

解决方案

然后我删除了构造函数中的行:

constructor(private readonly httpClient: HttpClient,
      private configService: ConfigService) { 
 }

只要在我需要的地方调用 apiBaseUrl 就可以了:

public get<T>(url: string): Observable<T> {
    return this.httpClient.get<T>(`${this.configService.apiBaseUrl}${url}`);
}