首页 > 解决方案 > Angular6 在模块 forRoot() 中使用获取的配置变量

问题描述

在我的应用程序中,我需要使用ng-intercom https://github.com/CaliStyle/ng-intercom,这需要在forRoot()方法中设置配置键。

配置键是从 API 调用加载的,在main.ts. 从 API 中获取配置,然后设置为APP_CONFIGin 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));
}

应用配置.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()密钥IntercomModule

app.module.ts

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 { }

配置示例:

{
  "production": true,
  "envName": "staging",
  "apiBaseURL": "//api.staging.site.com/v1/",
  "intercomKey": "qz0b98qo"
}

问题:初始化 IntercomModule 时,配置键未定义APP_CONFIG.intercomKey,因为尚未从 API 获取配置。

初始化模块时如何确保配置可用?有任何想法吗?

我之前尝试过在方法中调用一个函数,但是在使用 AOT 编译应用程序时forRoot()出错Function calls are not supported in decorators

另请参阅 stackblitz:https ://stackblitz.com/edit/angular6-intercom-issue

标签: angularangular-cli

解决方案


问题是 app.module.ts 中的代码在您将其导入 main.ts 后立即执行。您必须动态导入它以实现您的目标。我更新了您在 Stackblitz 上的示例以显示解决方案。

不过,您可能需要查看 TypeScript 是如何转换动态导入的。我不确定,目前是否可以针对广泛支持的 ES 版本。另请参阅此处有关该主题的 TypeScript 文档。

如果可以在服务器上请求和缓存应用程序配置,我认为这将是一个更干净的解决方案。


推荐阅读