Angular6在模块forRoot()中使用获取的配置变量 [英] Angular6 Using fetched config variable in module forRoot()

查看:92
本文介绍了Angular6在模块forRoot()中使用获取的配置变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my app I need to use ng-intercom https://github.com/CaliStyle/ng-intercom, which requires a config key to be set in forRoot() method.

config键是从API调用中加载的,该调用是在 main.ts 中完成的.从API获取配置,然后在 AppConfigService 中将其设置为 APP_CONFIG ,然后启动应用.

The config key is loaded from an API call, done in main.ts. The config is fetched from API, then set to APP_CONFIG in AppConfigService and then the app is bootstrapped.

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 并在 IntercomModule forRoot()中使用配置中的密钥代码>:

In AppModule I import the APP_CONFIG and use the key from the config in the forRoot() of the 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提取配置.

The problem: when the IntercomModule is initialized, the config key is undefined APP_CONFIG.intercomKey, because the config has not been fetched from API yet.

当模块初始化时,如何确保配置可用?有什么想法吗?

How do I make sure the config is available when the modules are initialized? Any ideas?

我之前曾尝试在 forRoot()方法中调用函数,但是出现错误装饰器不支持函数调用,当使用AOT编译应用程序时

I have tried calling a function in the forRoot() method before but got an error Function calls are not supported in decorators when compiling the app with AOT

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

See also stackblitz: https://stackblitz.com/edit/angular6-intercom-issue

推荐答案

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

The problem is that the code in app.module.ts is executed as soon as you import it in your main.ts. You have to dynamically import it to achieve your goal. I updated your example on Stackblitz to show a solution.

不过,您可能必须检查TypeScript如何转换动态导入.我不确定目前是否可以将目标定位为受广泛支持的ES版本.另请参阅主题此处.

You might have to check out how TypeScript is transpiling dynamic imports, though. I'm not sure, if it is currently possible to target an ES version that is widely supported. See also the TypeScript docs on the topic here.

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

If it is possible to request and cache the app-config(s) on the server, that would be a cleaner solution, in my opinion.

这篇关于Angular6在模块forRoot()中使用获取的配置变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆