Как отправить несколько действий ngrx одновременно - PullRequest
1 голос
/ 25 сентября 2019

Я использую ngrx и у меня есть scenerio, где мне нужно отправить 2 действия одновременно.Мое состояние имеет свойства для обновления и обновления и выглядит следующим образом.

//from reducer
const defaultCardState: CardState = {
    ids: [],
    entities: {},
    loaded: false,
    loading: false,
    adding: false,
    added: false,
    updating: false,
    updated: false,
    deleting: false,
    deleted: false
};

Это действия, которые я отправляю из моего компонента

this.store.dispatch(fromCard.updateCard({id: id1, changes: {name: name1}}))
this.store.dispatch(fromCard.updateCard({id: id2, changes: {name: name2}}))

Ниже приведены мои действия, средства уменьшения и эффекты

//Update Card Actions
export const updateCard = createAction('[Cards] Update Card', props<{id: string, changes: any}>())
export const updateCardSuccess = createAction('[Cards] Update Card Success', props<{changes: any}>());
export const updateCardFail = createAction('[Cards] Update Card Fail')

//Reducer
on(fromCards.updateCard, (state) => ({...state, updating: true, updated: false})),
    on(fromCards.updateCardSuccess, (state, action: any) => ({...cardAdapter.updateOne(action.changes, state), updated: true, updating: false})),
    on(fromCards.updateCardFail, (state, action: any) => fromCards.updateCardFail),

//Update Card Effect
updateCard$: Observable<Action> = createEffect(() => this.actions$.pipe(
    ofType(fromCardActions.updateCard),
    map((action: any) => { return {id: action.id, changes: action.changes}}),
    switchMap((action: any) => this.cardService.updateCard(action).pipe(
        map((res) => (fromCardActions.updateCardSuccess({changes: action }))),
        catchError(() => of(fromCardActions.updateCardFail))
    ))
))

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

Ответы [ 4 ]

2 голосов
/ 25 сентября 2019

Аналогично ответу Тони, но с использованием правильного оператора:

@Effect()
dispatchMultiAction$: Observable<Action> = this.actions$.pipe(
    ofType<SomeAction.Dispatch>(someActions.Dispatch),
    mergeMap(_ => [
            new someActions.InitData(),
            new someActions.GetData(),
            new someActions.LoadData()
        ])
    )
);
1 голос
/ 25 сентября 2019

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

0 голосов
/ 25 сентября 2019

Технически, это действительно плохая практика - использовать действие для отправки нескольких других действий.Это увеличивает усложняет применение.Через некоторое время вы не сможете отладить и понять, почему и какие действия будут отправлены.В этом видео Майк Райан описывает Good Action Hygiene с помощью NgRx: https://youtu.be/JmnsEvoy-gY?t=285

0 голосов
/ 25 сентября 2019

Вы можете отправить несколько действий в вашем эффекте, и я бы порекомендовал вам делать это только в эффекте

Рассмотрите пример ниже

@Effect()
dispatchMultiAction$: Observable<Action> = this.actions$.pipe(
    ofType<SomeAction.Dispatch>(someActions.Dispatch),
    switchMap(_ =>
        of(
            new someActions.InitData(),
            new someActions.GetData(),
            new someActions.LoadData()
        )
    )
);
...