我有一个模块(带有@NgModule),我需要导入一个模块:
MqttModule.forRoot(environment.MQTT_SERVICE_OPTIONS)
问题是我想从环境而不是从配置文件中获取值。
我已经创建了一个从配置文件加载属性的服务,但是我不知道如何在模块定义类中使用它。 我在某些组件中使用它,并且一切工作正常(只是通过构造函数注入),但是在这里我没有上下文。
答案 0 :(得分:1)
我已经创建了一个从配置文件中加载属性的服务,但是我不知道如何在模块定义类中使用它。
您不能使用Angular服务,因为这需要初始化注射器。在启动Angular中的任何东西之前,需要先配置 ngModule 。
root 模块由plaformBrowserDynamic().bootstrapModule(AppModule)
文件中的main.ts
行代码加载。这是Angular中所有内容的开始位置。
您只需要在执行此代码行之前加载配置,就不会有任何技术问题来延迟此操作。引导程序在此步骤进行的异步操作将显示空白页,直到操作完成为止,这会带来糟糕的用户体验。
我可以通过将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)
]
};
}
}
我强烈建议后端服务器将所需的配置数据注入index.html
中,以便不需要异步操作。然后,您可以在AppModule
中引用全局变量,并跳过withConfig()
步骤。 服务器应该负责Angular应用程序的引导状态 。