[英]Angular 6 - Initialize service with async calls before dependency injection
我有一个基于环境文件的服务,在内存中加载一个配置对象。 但是,设置的读取是异步的,应用程序甚至在所有设置都加载和崩溃之前就启动了。 在依赖注入完成之前,有什么方法可以“等待”这些函数。
我的服务:
import { Injectable } from '@angular/core';
import { IAppConfig } from '../models/app-config.model';
@Injectable()
export class AppConfig {
settings: IAppConfig;
version: any;
constructor() {
this.loadConfig();
}
// reads env.json file
// based on which environment it is loads config setting from
// environment specific config settings.
public loadConfig() {
return new Promise((resolve, reject) => {
const envFile = '/env.json';
this.readJsonFile(envFile).
then((envData) => {
const configFile = `assets/appconfigs/config.${envData.env}.json`;
this.version = envData.version;
this.readJsonFile(configFile).
then((configsettings) => {
this.settings = configsettings;
resolve(this.settings);
});
});
});
}
// reads json file and returns the json object promise
public readJsonFile(jsonUrl: string): any {
return new Promise((resolve, reject) => {
let retObject: any;
const xhr = new XMLHttpRequest();
xhr.overrideMimeType('application/json');
xhr.open('GET', jsonUrl, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
retObject = JSON.parse(xhr.responseText);
resolve(retObject);
} else {
reject(`Could not load file '${jsonUrl}': ${xhr.status}`);
}
}
};
xhr.send(null);
});
}
}
我希望在应用程序启动之前加载设置对象。 另一种方法是使这个类静态并调用 loadConfig 但这对测试平台来说是一场噩梦。 在模块中提供服务时有什么我可以指定的吗?
我不确定这个解决方案(未经测试的代码),但是我想您可以async/await
一切。
有什么理由不使用Angular的http
服务,而是使用手动XMLHttpRequest吗?
可能是这样的:
constructor() {
this.run()
}
async run() {
await this.loadConfig()
}
// reads env.json file
// based on which environment it is loads config setting from
// environment specific config settings.
public loadConfig() {
return new Promise( async (resolve, reject) => {
const envFile = '/env.json';
let envData = await this.readJsonFile(envFile)
const configFile = `assets/appconfigs/config.${envData.env}.json`;
this.version = envData.version;
this.settings = await this.readJsonFile(configFile);
resolve(); // No need to pass this.settings to resolve()
});
}
// reads json file and returns the json object promise
public readJsonFile(jsonUrl: string): any {
return this.http
.get(jsonUrl)
.map(res => res.json())
.toPromise()
}
我希望在应用程序启动之前加载设置对象。
您可以/应该使用注入令牌 APP_INITIALIZER: angular.io/APP_INITIALIZER
在你的情况下,像下面的代码就足够了。 在您的 AppModule 中:
{
provide: APP_INITIALIZER,
useFactory: initApp,
deps: [//add here services which depend on app-config
],
multi: true
}
export function initApp(appConfig: AppConfig) {
return () => appConfig.loadConfig();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.