Предоставьте InjectionToken после APP_INITIALIZATION с разрешенной конфигурацией

Мне нужно получить конфигурацию с помощью фабрики, которая будет разрешена во время ИНИЦИАЛИЗАЦИИ ПРИЛОЖЕНИЯ (с использованием поставщика APP_INITIALIZER).

      export function loadConfig(): () => Promise<Config> {
    // return promised config
}

Это предоставляется с помощью AppModule:

      providers: [{
  provide: APP_INITIALIZER,
  useFactory: loadConfig,
  deps: [HttpClient, ConfigService],
  multi: true
}]

Затем мне нужно использовать эти данные конфигурации для ввода чего-либо внутри другого InjectionToken, но если я предоставлю конкретный токен инъекции, используя конфигурацию, предоставленную во время инициализации приложения, этот процесс выполняется до выполнения APP_INITIALIZER.

      export const FORMATS = new InjectionToken<Formats>("formats")

export assignFormat(configService: ConfigService) {
    return configService.getFormats(); // Needs to execute after APP_INITIALIZER, not before
}
      providers: [{
  provide: APP_INITIALIZER,
  useFactory: loadConfig,
  deps: [HttpClient, ConfigService],
  multi: true
}, {
  provide: FORMATS,
  useFactory: assignFormat,
  deps: [ConfigService]
}]
      @Injectable({ providedIn: "root" })
export class ConfigService {
    constructor() {}
    getFormats() {}
}

Как я могу предоставить токен инъекции после инициализации приложения?

1 ответ

То, что у вас здесь, должно работать, если ваш loadConfigfactory возвращает функцию вместо фактического обещания :

      const loadConfig = (configService: ConfigService) => {
  return () =>
    new Promise<void>((resolve, reject) => {
      // I added the timeout to simulate a delay
      setTimeout(() => {
        // you might be using a http call to get the config from the server instead.
        // Make sure you keep the config that you fetched in the service;
        // this way you can inject the service in the next factory function 
        // and have the config available
        configService.config = {
          formats: 'formats',
        };
        resolve();
      }, 1000);
    });
};

Предоставление выглядит точно так же, как в вашем коде:

      {
  provide: APP_INITIALIZER,
  useFactory: loadConfig,
  deps: [ConfigService],
  multi: true,
},

Когда вы настраиваете следующий токен инъекции, у вас должна быть доступная конфигурация для использования.

      {
  provide: FORMATS,
  useFactory: (configService: ConfigService) => {
    // getFormats method must not be async, it needs to return the actual 
    // formats that were fetched during the app initialization phase
    return configService.getFormats();
  },
  deps: [ConfigService],
},

Единственные асинхронные фабрики, которые разрешены в Angular, - это те, которые вы используете с APP_INITIALIZERтокен инъекции , но имейте в виду, что из них вам нужно вернуть функцию вместо фактического значения.

Другие вопросы по тегам