如何从Ngrx的效果中分派多个动作

时间:2019-03-13 16:48:19

标签: angular ngrx

我正在使用datapersistence.pessimisticUpdate()遵循Ngrx的基本效果模式,像这样向服务器发布信息。

@Effect()
myUpdateCompleted$ = this.dataPersistence.pessimisticUpdate(MyActions.UpdateData, {

    run: (action: UpdateData, state: MyDataPartialState) => {
        return this.myDataService.updateData(action.payload)
            .pipe(
                map(result => ({
                    type: MyActions.ReloadData,
                    payload: result,
                })
                )
            );
    },

    onError: (action: UpdateData, error) => {
        console.error('Error', error);
        return new HandleUpdateDataError(error);
    }
});

我想在完成更新后重新加载数据。但是,在重新加载数据之前,我想通知用户更新已完成,现在正在执行数据重新加载。我打算的方法是在更新完成后分派两个动作。一种操作是通知用户(调度MyActions.NotifyMessage),另一种方法是重新加载数据(调度MyActions.ReloadData)。但是,数据持久性方法仅允许返回单个动作,而没有规定要分派一系列动作。我已经尝试过针对此问题发布的解决方案:

Dispatch multiple, ordered, actions from effect in NGRX

但是我得到了错误:

Property 'payload' does not exist on type 'Action' 

我该怎么做?是否应该转储使用数据持久性功能,并以其他方式返回多个操作?如果是这样,我如何在Ngrx效果中做到这一点?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

您可以为此使用`switchMap-Dispatching Multiple Actions from NGRX Effects

  db.Employee.find({$or:[{"EmployeeName":"Smith",{"EmployeeName":"Rajan","_id":30}}]})

答案 1 :(得分:0)

做到了。

import { Actions } from '@ngrx/effects';

    @Effect()
    save$: Observable<Notification | SaveSuccess> = this.actions$
        .ofType(MyActions.UpdateData)
        .pipe(
            switchMap(action => this.myService.save(action.payload)),
            switchMap(res => {
                return [
                   new Notification('save success'), 
                   new SaveSuccess(res)
                ];
        })
    );

this.actions$需要import { Actions } from '@ngrx/effects';

除此之外,如果您必须从原始动作有效载荷中传递数据,则必须像这样使用concatMap(注意-以下示例仅传递了整个动作,而不仅仅是有效载荷):

import { Actions } from '@ngrx/effects';

    @Effect()
    save$: Observable<Notification | SaveSuccess> = this.actions$
        .ofType(MyActions.UpdateData)
        .pipe(

            // The difference is in this switchMap
            switchMap(action => { 
                return this.myService.save(action.payload).pipe(
                    concatMap<any, UpdateData>(() => of(action)) 
                );                
            }),

            switchMap(origAction => {
                return [
                   new Notification('save success'), 
                   new SaveSuccess(origAction.payload)
                ];
        })
    );

希望这可以像我一样帮助任何为此苦苦挣扎的人。

答案 2 :(得分:0)

这对我有用:

    throwMultipleActions$ = createEffect(() =>
        this.actions$.pipe(
            ofType(ThrowMultipleActions),
            switchMap(({ payload }) => {
                const actionsToThrow = [];
                payload.forEach(el => {
                    actionsToThrow.push(attachAction(el));
                });
                return actionsToThrow
            }),
            catchError((error) => {
                return observableOf(ThrowMultipleActionsFail({ payload: error }));
            })
        ));
    const attachAction = (el: { actionName: string; payload: any }) => {
        const { actionName, payload } = el;
        switch (actionName) {
            case 'SetFilter':
                return SetFilter({ payload });
            case 'GetAllCompanys':
                return GetAllCompanys({ payload });
            default:
                break;
        }
    };

//Example throwing multiple actions:

this.clientStore.dispatch(
            ThrowMultipleActions({
                payload: [
                    { actionName: 'SetFilter', payload: this.filtros },
                    { actionName: 'GetAllCompanys', payload: this.filtros },
                ],
            })
        );