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}`);
}
我一直在尝试在 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}`);
}