首页 > 解决方案 > Angular APP_INITIALIZER

问题描述

我是 Angular 的新手,目前使用 Angular6 进行开发。这是我的查询。在我的应用程序启动之前,我需要调用三个服务来为我提供一些应用程序的配置。让我们将这些服务称为 Initialization、Conifg 和 UserDetails。所以我在 app-module.ts 文件中添加了服务,如下所示。

`

    export function init_app(initService: InitializationService) {
        return () => initService.getInit();
    }

    export function get_settings(configService: ConfigService) {
        return () => configService.getConfig();
    }
export function get_user_settings(userDetails: UserDetailsService) {
        return () => userDetails.getSettings();
    }

    @NgModule({
      imports: [/*my-imports*/],
      providers: [
        AppLoadService,
        { provide: APP_INITIALIZER, useFactory: init_app, deps: [InitializationService], multi: true },
        { provide: APP_INITIALIZER, useFactory: get_settings, deps: [ConfigService], multi: true },
        { provide: APP_INITIALIZER, useFactory: get_user_settings, deps: [UserDetailsService], multi: true }
      ]
    })

` 现在 InitializationService 具有其他两个服务正常工作所需的一些值。在 app_init 中,服务请求会立即发送。

我需要仅在完成对 InitializationService 的调用后才调用我的 ConfigService 和 UserDetailsS​​ervice。

为了解决这个问题,我做了以下工作,

// AppConfig.ts

export class AppConfig {
  public static Config= {};

  public static $subject = new Subject();
}

// 初始化服务

getInit () {

const promise = new Promise((resolve, reject) => {
      this.http.get().then(val => {
        AppConfig.config = val;
        AppConfig.$subject.next(val);
      });
};

return promise;
}

//配置服务

getConfig () {
 if(AppConfig.Config.baseUrl === undefined) {
   AppConfig.$subject.subscribe(val => {
     this.http.get(AppConfig.Config.baseUrl).then(//doSomething);
   })
 }
}

所以我创建了一个静态主题并订阅它。一旦 Init 服务完成,它会发送主题的下一个值,现在由 Config 服务订阅和侦听。收到订阅电话后,我会进行进一步的操作。

我的 UserDetails getSettings() 调用重复了相同的代码。

我的方法正确吗?是否有任何其他模式经过尝试和测试。

有什么建议或更好的方法来解决上述问题吗?

提前致谢。

问候, hawx

标签: angulartypescriptrxjsobserver-pattern

解决方案


使用一个初始化程序并控制那里的整个流程:

export function initAll(initService: InitializationService, configService: ConfigService, userDetails: UserDetailsService) {
  return () => {
    return initService.getInit().pipe(
      switchMap(() => {
        return flatMap([ConfigService.getConfig(), userDetails.getSettings()]);
      }),
    );
  }
}

请注意,flatMap假设两个操作都已完成;然而,这只是可行的方法。您可以完全控制 rxjs 运算符的过程。而且,你只有一个APP_INITIALIZER


推荐阅读