Угловой APP_INITIALIZER - PullRequest
       11

Угловой APP_INITIALIZER

0 голосов
/ 16 сентября 2018

Я новичок в 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 запрос на услуги отправляется немедленно.

Мне нужно, чтобы мои ConfigService и UserDetailsService вызывались только после завершения вызова InitializationService.

Для решения этой проблемы я сделал следующее:

// AppConfig.ts

export class AppConfig {
  public static Config= {};

  public static $subject = new Subject();
}

// InitializationService

getInit () {

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

return promise;
}

// ConfigService

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

Итак, я создаю статическую тему и подписываюсь на нее.Как только служба Init завершена, она отправляет следующее значение для субъекта, который теперь подписан и прослушивается службой Config.Как только вызов подписки получен, я делаю свою дальнейшую операцию.

Тот же код повторяется моим вызовом UserDetails getSettings ().

Правильный ли мой подход?Есть ли какие-либо другие образцы, опробованные и протестированные.

Любое предложение или лучший способ решения вышеуказанного?

Заранее спасибо.

С уважением, hawx

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

// код модуля приложения

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

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

// вызов службы конфигурации

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

Я воспользовался этим подходом, потому что он решает мою проблему наличия и поддержания предмета. Кроме того, у меня было мало времени, чтобы попытаться отладить то, что пошло не так с наблюдаемыми вещами.

Спасибо за ответ, хотя.

0 голосов
/ 16 сентября 2018

Используйте один инициализатор и управляйте всем потоком там:

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

...