Зависящие от конвейера действия в NgXS

#angular #rxjs #ngxs

#angular #rxjs #ngxs

Вопрос:

У меня есть несколько действий, которые мне нужно объединить в одно действие для вызова.

Пусть у меня есть состояние:

 const store = {
  id: number;
  magic: string;
  value1: string;
}

@Action(LoadMagic)
public LoadMagic({getState, setState, dispatch}, action: {id: number}) {
  const obj = _http.get(action.id);
  setState({ id: action.id, magic: obj.magic });
}

@Action(LoadValue1)
public LoadValue1({getState, setState, dispatch}, action: {id: number, magic??}) {
  const magic = ???; //getState().magic
  const value2 = _http.get(action.id, magic);
  setState({ value2 });
}
 

Итак, теперь, в конце концов, мне нужно создать действие, которое будет выполнять эти 2 действия. Но, как вы можете видеть, для действия LoadValue1 требуется значение, возвращаемое из LoadMagic. Итак, я ищу что-то вроде:

 @Action(SuperAction)
public SuperAction({getState, setState, dispatch}, action: {id: number}) {
  dispatch([
    new LoadMagic(action.id),
    () => new LoadValue1(action.id, getState().magic) //you can't pass the function
  ]);
}
 

Итак, второе действие в dispatch является своего рода ленивым. Но, в конце концов, такой подписи нет.

Конечный результат похож на:

 @Action(SuperAction)
public SuperAction({getState, setState, dispatch}, action: {id: number}) {
  dispatch(new LoadMagic(action.id))
    .pipe(mergeMap(() => dispatch(new LoadValue1(action.id, getState().magic)));
}
 

Комментарии:

1. Вау, я не уверен, что именно так вы хотели бы решить эту проблему. Я бы рекомендовал прочитать о жизненных циклах действий: ngxs.io/advanced/actions-life-cycle . Похоже, вам просто нужно использовать некоторые rxjs, чтобы лучше обрабатывать ваши http-вызовы. Мой совет был бы выяснить, как решить эту проблему без действий, затем понять, как работают действия, а затем выяснить, могут ли действия помочь или нет.

Ответ №1:

Действия на самом деле не должны иметь возвращаемых значений. Если вы хотите использовать что-то, что было изменено в состоянии, вы можете сделать это, как показано ниже:

 @Select(MagicState.magicSelector) magic$: Observable<any>;

dispatch(new LoadMagic(action.id))
  .pipe(withLatestFrom(magic$), mergeMap(([_, magic]) => dispatch(new LoadValue1(action.id, magic)));
 

Комментарии:

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

Ответ №2:

Зависимое действие может быть передано по конвейеру. И окончательный наблюдаемый объект должен быть возвращен в NgXS, чтобы он автоматически подписался на него и правильно выполнил действие.

 @Action(SuperAction)
public SuperAction({getState, setState, dispatch}, action: {id: number}): Observable<void> {
  return dispatch(new LoadMagic(action.id))
    .pipe(switchMap(() => dispatch(new LoadValue1(action.id, getState().magic)));
}