在我的应用中,我需要使用ng-intercom
https://github.com/CaliStyle/ng-intercom,这需要在forRoot()
方法中设置配置键。
从main.ts
完成的API调用中加载配置密钥。从API获取配置,然后在APP_CONFIG
中将其设置为AppConfigService
,然后启动应用。
main.ts
const appConfigRequest = new XMLHttpRequest();
appConfigRequest.addEventListener('load', onAppConfigLoad);
appConfigRequest.open('GET', 'https://api.myjson.com/bins/lf0ns');
appConfigRequest.send();
// Callback executed when app config JSON file has been loaded.
function onAppConfigLoad() {
const config = JSON.parse(this.responseText);
initConfig(config);
}
// Sets fetched config to AppConfigService constant APP_CONFIG and calls bootstrap()
function initConfig(config) {
const injector = ReflectiveInjector.resolveAndCreate([AppConfigService]);
const configService = injector.get(AppConfigService);
configService.set(config);
bootstrap();
}
function bootstrap() {
platformBrowserDynamic().bootstrapModule(AppModule).then().catch(err => console.error(err));
}
app-config.service.ts
import { Injectable } from '@angular/core';
export let APP_CONFIG: any = {};
@Injectable()
export class AppConfigService {
constructor() {}
public set(config) {
APP_CONFIG = Object.assign(config);
}
}
在AppModule
中,我导入APP_CONFIG
并使用forRoot()
的{{1}}中的配置密钥:
app.module.ts
IntercomModule
配置示例:
import { NgModule, InjectionToken, Inject, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { APP_CONFIG } from './../shared/services/app-config.service';
import { IntercomModule } from 'ng-intercom';
@NgModule({
imports: [
BrowserModule,
FormsModule,
IntercomModule.forRoot({
appId : APP_CONFIG.intercomKey,
updateOnRouterChange: false
})
],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
问题:初始化IntercomModule时,未定义配置密钥{
"production": true,
"envName": "staging",
"apiBaseURL": "//api.staging.site.com/v1/",
"intercomKey": "qz0b98qo"
}
,因为尚未从API提取配置。
当模块初始化时,如何确保配置可用?有什么想法吗?
我之前曾尝试在APP_CONFIG.intercomKey
方法中调用函数,但是在使用AOT编译应用程序时却遇到了错误forRoot()
另请参阅stackblitz:https://stackblitz.com/edit/angular6-intercom-issue
答案 0 :(得分:1)
问题在于,一旦将app.module.ts中的代码导入到main.ts中,该代码就会立即执行。您必须动态导入它才能实现目标。我更新了您的example on Stackblitz以显示解决方案。
不过,您可能必须检查TypeScript如何转换动态导入。我不确定当前是否可以将目标定位为受广泛支持的ES版本。另请参阅关于主题here的TypeScript文档。
在我看来,如果可以在服务器上请求并缓存app-config,那将是一个更干净的解决方案。
答案 1 :(得分:0)
我遇到了类似的问题,@ realhans的回答也使我无法使用AOT。
here中提到的解决方案可以在AOT继续工作的同时解决该问题。