APP_INITIALIZER不阻止导入的模块

时间:2018-09-27 19:40:00

标签: angular

我有一个Angular(v6.0.0)应用程序,该应用程序试图在APP_INITIALIZER期间引入运行时配置的情况下进行设置。我已经阅读了几篇文章(例如thisthisthis)和诸如this之类的问题,并且基本上使一切正常。

我让应用程序调用配置服务功能,以在应用程序引导时(在APP_INITIALIZER期间)加载配置。一切都完美。问题在于应用程序的其他部分正在加载/初始化/在构造加载之前调用了它们的构造函数,因此无法使用文件中的配置。以下是app.module文件的摘录:

function initConfig(configService: AppConfigService) {
    return () => configService.loadConfig();
}

...

@NgModule({
    imports: [AuthModule, SharedModule]
    providers: [
        {
            provide: APP_INITIALIZER,
            useFactory: initConfig,
            deps: [AppConfigService],
            multi: true
        },
        ...
    ]
})

和AppConfigService文件:

public loadConfig() {
    return this._http.get('./assets/app-config/config.json')
        .toPromise()
        .then((config: any) => {
            this.config = config;
        })
}

如您所见,loadConfig函数返回一个promise,并且配置已加载(我已经确认)。

但是,我尝试访问AuthModule构造函数中的配置(以便我可以提取服务器身份验证所需的配置值)和SharedModule中的服务(在这种情况下正在寻找Sentry DSN) ,并且它们都在加载配置之前运行。我敢肯定还会有其他示例,但这是我到目前为止发现的。

我的印象是,APP_INITIALIZER解决之前,应用程序中的任何内容都无法加载,但是显然不是这种情况。有什么我想完成的吗?我可以做些什么使所有其他模块在初始化之前等待配置加载吗?如果不是这样,它将根本无法实现运行时配置的目的。

1 个答案:

答案 0 :(得分:0)

我最近遇到了您面临的问题。不幸的是,众所周知,APP_INITIALIZER不会阻止模块的导入。您可以使用全局窗口对象来附加您的配置数据。这样,就可以在整个应用程序中全局访问数据。

public loadConfig() {
    return this._http.get('./assets/app-config/config.json')
        .toPromise()
        .then((config: any) => {
            window['appConfigData'] = config;
            this.config = config;
        })
}

在属于SharedModule的服务中,您只需从窗口对象访问配置数据即可。

constructor() {
  ..
  ..
    const configData = window['appConfigData'];
}