Angular - 在模块定义中使用动态变量

标签 angular

我有一个模块(带有@NgModule),我需要导入一个模块:

MqttModule.forRoot(environment.MQTT_SERVICE_OPTIONS)

问题是我不想从环境中而是从配置文件中获取值。

我创建了一个从配置文件加载属性的服务,但我不知道如何在模块定义类中使用它。 我在某些组件中使用它并且一切正常(只是通过构造函数注入(inject)),但在这里我没有上下文。

最佳答案

I've created a service that loads the properties from a config file but I don't know how to use it in the module definition class.

您不能使用 Angular 服务,因为这需要初始化注入(inject)器。 ngModule 需要在 启动 Angular 中的任何内容之前进行配置。

root 模块由 main.ts 文件中的 plaformBrowserDynamic().bootstrapModule(AppModule) 代码行加载。这是 Angular 中一切开始的地方。

你只需要在执行这行代码之前加载你的配置,不存在延迟此操作的技术问题。 Bootstrap 中此步骤的异步操作将显示空白页面,直到操作完成,这会导致糟糕的用户体验。

我可以通过将 main.ts 更改为以下内容来演示效果:

(function () {
    return new Promise(resolver => {
        window.setTimeout(() => resolver(), 5000);
    });
})().then(() => {
    platformBrowserDynamic().bootstrapModule(AppModule)
        .catch(err => console.log(err));
});

以上只是将 Angular 的引导延迟 5 秒。

这是您不应该在应用程序启动时异步加载资源的一个很好的理由,但如果您真的想这样做,没有理由不这样做。

您需要更改 promise ,使其解析为您需要的配置设置,然后将其传递给 AppModule 中的静态函数。

我将更新我的示例,但假设您的最终源代码正在为远程配置文件发出 HTTP 请求。

(function () {
    return new Promise(resolver => {
        const exampleConfig = {
            options: 'ABC'
        };
        window.setTimeout(() => resolver(exampleConfig), 5000);
    });
})().then(config => {
    platformBrowserDynamic().bootstrapModule(AppModule.withConfig(config))
        .catch(err => console.log(err));
});

您现在必须为 AppModule 手动创建模块定义,但这与模块实现 forRoot() 方法的方式完全相同。我刚刚将它重命名为 withConfig() 这样听起来更好。

@NgModule()
export class AppModule {
    static withConfig(config: any): ModuleWithProviders {
        return {
            ngModule: AppModule,
            imports: [
                MqttModule.forRoot(config)
            ]
        };
    }
}

我强烈建议后端服务器将所需的配置数据注入(inject)到 index.html 中,这样就不需要异步操作了。然后您可以在 AppModule 中引用全局变量并跳过 withConfig() 步骤。 服务器 应该负责 Angular 应用程序的引导状态

关于Angular - 在模块定义中使用动态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54202666/

相关文章:

javascript - 在 Angular 2 App 中的已迭代集合中迭代时 *ngFor 的语法

angular - 如何为 ngFor 中的每个元素显示模态?

angular - 为什么 Material Design 的布局不能与 Angular 4 兼容?

unit-testing - Angular2 组件 : Testing form input value change

javascript - 使用深层链接的 ng bootstrap 下拉菜单样式

同一组件和 View 中的Angular Material Multiple Paginator

Angular 2 从 ComponentInstruction 获取 URL

angular - 如何禁用从任何组件调用的 Angular 右键单击功能

javascript - 在 Angular-CLI 项目中使用 mdTooltip

javascript - 在不同端口的本地主机上的 2 个 Angular SPA 之间共享 sessionStorage