Angular DI - useFactory - Provider: есть ли способ вызвать функцию Provider Factory во второй раз, когда обновляется локальное состояние? - PullRequest
0 голосов
/ 24 августа 2018

Сценарий выглядит следующим образом:

1. В приложении есть корневой модуль, а конструктор разрешает Promise и возвращает константу.

@NgModule({
    ....,
    providers : [
    ...
    { 
      provide: SAMPLE_INJECTOR_TOKEN,
      useFactory: sampleFactoryFn(SAMPLE_GLOBAL_CONSTANT.DATA)
    }
       ]
})
export class AppModule {
 constructor() {
  // To be clear: This code runs on window.onLoad(). window argument is actually window object
  setupPromiseAPI(window).then(data => {
   SAMPLE_GLOBAL_CONSTANT.DATA = data; // Once promise resolves this gets expected value. [ Step 3 ]
  }).catch({
      ...
  })

}

2. Поскольку это значение является объектом, а также, поскольку оно будет доступно во время выполнения, я создал токен инъекции с использованием «useFactory» и зарегистрировался на уровне модуля.

// Injector Token    
export SAMPLE_INJECTOR_TOKEN = new InjectionToken<CustomDataType>('SampleInjectorToken');

// Factory Function
export function sampleFactoryFn(data: CustomDataType) {
       return (/* No deps to be passed */): CustomDataType => data; // simply return what ever it received.
            }

3. Я создал глобальную константу, инициализированную нулем и переданную в качестве аргумента заводской функции, с помощью которой angular создает токен инжектора и присваивает значение null (начальное состояние) при начальной загрузке.

export const SAMPLE_GLOBAL_CONSTANT = {
    DATA: null // Initial State
}

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

Кроме того, угловая документация гласит, что поставщик useFactory лениво создает свое значение, которое, насколько я понимаю, будет создано при его внедрении. Если это так, к тому времени, когда код вводит мой токен инъекции, глобальная константа обновляется. Тем не менее токен инжектора имеет нулевое значение.

Q1. Есть ли способ вызвать функцию фабрики провайдера с обновленным локальным состоянием, чтобы мой токен инжектора получил значение?

Q2. Так как я использую глобальную константу, она делает код работающим, но не слабо связанным, что также затрудняет модульное тестирование. Есть ли альтернативы потреблять полученную константу и использовать ее в коде, чтобы она была слабо связана?

1 Ответ

0 голосов
/ 09 октября 2018

Один из способов, который я решил, это использование Replay Subject из RxJS. Прежде всего, это сервис postMessage, завернутый в обещание. Таким образом, после того, как сообщение было отправлено (из другого приложения) и обещание было разрешено (при использовании приложения), должен быть способ хранения этих данных для их использования в приложении.

Использование субъекта воспроизведения со значением буфера 1, что означает воспроизведение последнего значения в подписке, действительно выдает последнее пойманное значение после разрешения вышеуказанного сценария.

Затем передайте полученные данные в Angular Service по подписке, что сделает их доступными через приложение.

Теперь это делает необходимые данные в угловой службе, а не в глобальной константе, что упрощает модульное тестирование.

NB: Factory Provider не разрешает эту ситуацию, потому что angular пытается разрешить до того, как произойдет запуск, который по умолчанию равен инициализированному значению (в моем случае это было нулевое значение). Так что это не сработает.

Почему бы не асинхронный субъект?

Поскольку Async Subject получает сигнал только после завершения, а бизнес-пример, который я решаю, должен выполнить промежуточную работу, прежде чем объявить сигнал завершения. Это не решило цель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...