Angular:如何正确实现APP_INITIALIZER

Pal*_*lmi 15 typescript angular

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

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

这里是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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

export class TestComponent {
    public test1ServiceUrl: string;

    constructor(public configService: ConfigurationService) {
        this.test1ServiceUrl = this.configService.config.test1ServiceUrl;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Est*_*ask 18

由于APP_INTIALIZER 工作原理,预计异步初始化器会返回promise,但是你的APP_INTIALIZERmultiprovider实现不会因为loadConfigurationData函数没有返回任何东西.

它应该是这样的:

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

  • 现在应该使用 `pipe`/`tap`,而不是 `do`。 (7认同)
  • 这是不特定于此情况的Angular / RxJS通用知识。如果使用RxJS运算符,则需要先导入它。您可能为其他操作员执行了此操作。应该有类似import'rxjs / add / operator / do`之类的东西。参见/sf/ask/2966388071/ (2认同)
  • 一个重要的“安全提示”。你真的必须返回一个 Promise...尝试直接返回可观察值是行不通的,它不会告诉你它不起作用,它只是...不起作用。 (2认同)