Angular:如何正确实现APP_INITIALIZER

时间:2018-04-07 13:24:48

标签: angular

我有一个 Angular 5.2.0 应用程序。 我查看了如何在应用程序启动之前实现APP_INITIALIZER来加载配置信息。 这是app.module的摘录:

providers: [
    ConfigurationService,
    {
        provide: APP_INITIALIZER,
        useFactory: (configService: ConfigurationService) =>
            () => configService.loadConfigurationData(),
        deps: [ConfigurationService],
        multi: true
    }
],

此处为configuration.service

import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Configuration } from './configuration';

@Injectable()
export class ConfigurationService {
    private readonly configUrlPath: string = 'Home/Configuration';
    private configData: Configuration;

    constructor(
        private http: HttpClient,
        @Inject('BASE_URL') private originUrl: string) { }

    loadConfigurationData() {
        this.http
            .get<Configuration>(`${this.originUrl}${this.configUrlPath}`)
            .subscribe(result => {
                this.configData = {
                    test1ServiceUrl: result["test1ServiceUrl"],
                    test2ServiceUrl: result["test2ServiceUrl"]        
                }
            });
    }

    get config(): Configuration {
        return this.configData;
    }
}

以下是使用configData的组件构造函数的示例:

export class TestComponent {
    public test1ServiceUrl: string;

    constructor(public configService: ConfigurationService) {
        this.test1ServiceUrl = this.configService.config.test1ServiceUrl;
    }
}

它适用于<router-outlet></router-outlet>中定义的所有组件。但是<router-outlet></router-outlet>之外的组件中的相同实现不起作用 当我调试组件的相应构造函数时,它表示configServicenull
为什么在APP_INITIALIZER内的组件的构造函数之前执行<router-outlet></router-outlet>而不是在<router-outlet></router-outlet>之外的组件的构造函数之前执行?

3 个答案:

答案 0 :(得分:9)

由于APP_INTIALIZER works的方式,它预计异步初始值设定项会返回承诺,但是APP_INTIALIZER多提供商的实现并不是因为loadConfigurationData功能不会返回任何内容。

应该是这样的:

loadConfigurationData(): Promise<Configuration> {
  return this.http.get<Configuration>(`${this.originUrl}${this.configUrlPath}`)
  .do(result => {
    this.configData = result;
  })
  .toPromise();
}

答案 1 :(得分:0)

做类似

 export function StartupServiceFactory(startupService: StartupService) {
      return () => startupService.load();
    }
    const APPINIT_PROVIDES = [
      StartupService,
      {
        provide: APP_INITIALIZER,
        useFactory: StartupServiceFactory,
        deps: [StartupService],
        multi: true,
      },
    ];

启动服务

load():Promise{
    return new Promise(resolve, reject){
        //load all your configuration 
         resolve(); 
    }

  }

答案 2 :(得分:-1)

我有类似的问题。解决方法基本相同,实际上返回了承诺。 参见:ngOnInit starts before APP_INITIALIZER is done