Правильный способ доступа к хранилищу в ngrx / effect

Я использую Angular 6, ngrx / store, ngrx / effects. У меня есть эффект, который должен срабатывать, когда я нажимаю кнопку «Сохранить». Я использую withLatestFrom там для сбора всех данных, которые мне нужны для отправки на сервер:

@Effect({dispatch: false})
  saveAll$ = this.actions$.pipe(
    ofType(ActionTypes.Save),
    withLatestFrom(
      this.store.select(fromReducers.getData1),
      this.store.select(fromReducers.getData2),
      this.store.select(fromReducers.getData3),
      this.store.select(fromReducers.getData4)
    ),
    switchMap(([action, data1, data2, data3, data4]: [ActionType, Data1[], Data2[], Data3[], Data4[]]) => {
       // here is some operations with these data
       return this.apiService.saveData({data1, data2, data3, data4})
    })
)

Вот селектор getData1:

export const getData1= createSelector(
  getItems,
  getIndexes,
  (items, indexes) => {
    console.log('HI, I AM getData1');
    return transformItems(items, indexes);
  }
);

getItems, в свою очередь, возвращают state.items. Проблема в том, что state.items можно изменить другим эффектом:

@Effect()
  handleItemsChanges$ = this.actions$.pipe(
    ofType(ActionTypes.ChangesInItems),
    withLatestFrom(
      this.store.select(fromReducers.getItems),
      this.store.select(fromReducers.getUsers),
    ),
    switchMap(([action, items, users]: [ActionType, Item[], User[]]) => {
       console.log('I AM handleItemsChanges');
       const actions = [];
       if (itemsShouldBeUpdated) {
          actions.push(new UpdateData(changes))
       }
    })
)

Таким образом, селектор getData1 получает данные из хранилища в зависимости от другого эффекта с именем handleItemsChanges. handleItemsChanges эффект срабатывает каждый раз, когда что-то меняется, связанное с предметами, и пересчитывает это заново. В результате в saveAll я получаю не актуальный state.items. Что я делаю неправильно? Может быть, мне стоит использовать другой оператор вместо withLatestFrom или что может быть решением? Спасибо

P.S. Кстати, я использую withLatestFrom каждый раз, когда хочу получить данные из магазина. Это правильно?


person mr__brainwash    schedule 07.06.2018    source источник
comment
Вы можете написать один селектор, который будет получать все данные. ИЛИ вы можете отправить все необходимые данные в качестве полезной нагрузки.   -  person Pavan Bahuguni    schedule 08.06.2018
comment
Вы могли бы поискать это в поисках решения. medium.com/@viestursv/   -  person chirag    schedule 01.04.2020


Ответы (2)


вам нужно, чтобы действие handleItemsChanges было запущено до того, как saveAll будет запущено. Один из способов сделать это - создать эффект для действия handleItemsChanges и запустить действие save.

Фреймворк гарантирует порядок выполнения (сначала handleItemsChanges, затем save), таким образом операция withLatestFrom будет работать так, как вы ожидали.

person Derek Liang    schedule 27.10.2018

Я нашел обсуждение на ngrx github: https://github.com/ngrx/platform/issues/467 Похоже, у нас есть 2 уродливых варианта доступа к магазину из эффектов.

person Mihail    schedule 12.12.2018