#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)));
}