简体   繁体   English

角度APP_INITIALIZER

[英]Angular APP_INITIALIZER

I am new to Angular and currently using Angular6 for development purpose. 我是Angular的新手,目前正在使用Angular6进行开发。 Here is my query. 这是我的查询。 Before my app starts I need to call three services that provide me some configs for the app. 在我的应用程序启动之前,我需要调用三个服务,为我提供一些应用程序配置。 Lets call the services as Initialization, Conifg and UserDetails. 让我们将服务称为Initialization,Conifg和UserDetails。 So I have added the services in the app-module.ts file as below. 因此,我将服务添加到了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 }
      ]
    })

` Now InitializationService has some values that are needed by the other two services to work properly. 现在,InitializationService具有其他两个服务正常工作所需的一些值。 In app_init the services request are sent immediately. 在app_init中,服务请求将立即发送。

I need my ConfigService and UserDetailsService to be called only when the call for InitializationService is done. 我只需要在完成InitializationService调用后才能调用ConfigService和UserDetailsS​​ervice。

To tackle this I have done following, 为了解决这个问题,我做了以下工作

// AppConfig.ts // AppConfig.ts

export class AppConfig {
  public static Config= {};

  public static $subject = new Subject();
}

// InitializationService // InitializationService

getInit () {

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

return promise;
}

//ConfigService //的ConfigService

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

So i create a static subject and subscribe to it. 所以我创建一个静态主题并订阅它。 Once the Init service is done, it sends the next value for the subject, which is now subscribed and listened by Config service. 初始化服务完成后,它将发送主题的下一个值,该值现在已由Config服务订阅和侦听。 Once the subscribe call is received I do my further operation. 收到订阅电话后,我将进行进一步的操作。

Same code is repeated by my UserDetails getSettings() call. 我的UserDetails getSettings()调用重复相同的代码。

Is my approach correct? 我的方法正确吗? Is there any other pattern tried and tested. 是否有其他尝试和测试过的模式。

Any suggestion or better way to tackle the above? 有什么建议或更好的方法来解决上述问题?

Thanks in advance. 提前致谢。

Regards, hawx 问候,山楂树

Use one initialiser and control the whole flow there: 使用一个初始化程序并控制那里的整个流程:

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

Please note that flatMap assumes both operations to be completed; 请注意, flatMap假定这两个操作都将完成。 however this is just the approach to go. 但是,这只是要走的路。 You have full control to the process over rxjs operators. 您可以完全控制rxjs运算符的过程。 And, you have only one APP_INITIALIZER 而且,您只有一个APP_INITIALIZER

//app-module code //应用模块代码

export function initAll(appInitService:AppInitService, configService:ConfigService) {
  // return a promise because thats what the app_init token expects. there is an open ticket with angular related to this. https://github.com/angular/angular/issues/15088
  return () => {
    const promise = new Promise((resolve, reject) => {
      appInitService.load().then(() => {
        configService.fetch().then(() => {
          resolve();
        });
      });
    });
    return promise;
  }
}

//appInitService.load() call //appInitService.load()调用

const promise = this.http.get<any>(`myConfigURL`).toPromise();
promise.then(response => {
 Object.assign(AppConfig.ENV, response.value.parameters);
});
return promise;

// config service call //配置服务调用

const promise = this.http.get<any>(myConfigUrl).toPromise();
promise.then(response => {
  //do something with response
});
return promise;

I took this approach because it solves my problem of having and maintaining Subject. 我采用这种方法是因为它解决了我拥有和维护Subject的问题。 Plus I was short on time to try and debug of what was going wrong with the Observable stuff. 另外,我的时间很短,无法尝试调试Observable东西出了什么问题。

Thanks for the response though. 感谢您的回复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM