本文介绍了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.

配置键是从 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.

ma​​in.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 并使用 IntercomModuleforRoot() 配置中的密钥代码>:

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时,config key未定义APP_CONFIG.intercomKey,因为尚未从API中获取config.

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 版本.另请参阅有关主题的 TypeScript 文档 此处.

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.

如果可以在服务器上请求和缓存 app-config(s),在我看来,这将是一个更简洁的解决方案.

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() 模块中使用获取的配置变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 11:00