Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何同时调度多个ngrx操作_Angular_Typescript_Redux_Rxjs_Ngrx - Fatal编程技术网

Angular 如何同时调度多个ngrx操作

Angular 如何同时调度多个ngrx操作,angular,typescript,redux,rxjs,ngrx,Angular,Typescript,Redux,Rxjs,Ngrx,我正在使用ngrx,有一个场景,我需要同时调度两个动作。我的状态有更新和更新的属性,如下所示 //from reducer const defaultCardState: CardState = { ids: [], entities: {}, loaded: false, loading: false, adding: false, added: false, updating: false, updated: false,

我正在使用ngrx,有一个场景,我需要同时调度两个动作。我的状态有更新和更新的属性,如下所示

//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))
    ))
))
//更新卡操作
export const updateCard=createAction(“[Cards]更新卡”,props())
export const updateCardSuccess=createAction(“[Cards]更新卡成功”,props());
export const updateCardFail=createAction(“[Cards]更新卡失败”)
//减速器
在(fromCards.updateCard,(state)=>({…state,updated:true,updated:false})上,
在(fromCards.updateCardSuccess,(state,action:any)=>({…cardapter.updateOne(action.changes,state),updated:true,update:false})上,
on(fromCards.updateCardFail,(状态,操作:any)=>fromCards.updateCardFail),
//更新卡片效果
updateCard$:Observable=createEffect(()=>this.actions$.pipe(
类型(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))
))
))

一个接一个地分派这些操作以使更新字段和更新字段不冲突的最佳方法是什么?如果我只运行其中一个,它会工作,但如果我像上面所示将它们一起分派,则只有一个完成。我看到两个操作都被调度,但只有一个成功操作被调度。

如果没有,则您有一个不同的操作,该操作的有效负载是一个卡阵列而不是一个卡,然后减速器返回使用多个卡更新的新状态。您的api还应该能够获取一个数组,以便您的效果可以向服务器发送多个操作。

您可以在效果中发送多个操作,我建议您仅在效果中这样做

考虑下面的例子

@Effect()
dispatchMultiAction$: Observable<Action> = this.actions$.pipe(
    ofType<SomeAction.Dispatch>(someActions.Dispatch),
    switchMap(_ =>
        of(
            new someActions.InitData(),
            new someActions.GetData(),
            new someActions.LoadData()
        )
    )
);
@Effect()
dispatchMultiAction$:Observable=此.actions$.pipe(
类型(someActions.Dispatch),
开关映射(=>
的(
新建someActions.InitData(),
新建someActions.GetData(),
新建someActions.LoadData()
)
)
);

从技术上讲,使用action分派另一个多个action是非常糟糕的做法。这增加了应用的复杂性。一段时间后,您将无法调试和理解为什么和被调度的操作。本视频Mike Ryan介绍了NgRx的良好行动卫生:

与Tony的答案类似,但使用正确的运算符:

@Effect()
dispatchMultiAction$: Observable<Action> = this.actions$.pipe(
    ofType<SomeAction.Dispatch>(someActions.Dispatch),
    concatMap(_ => [
            new someActions.InitData(),
            new someActions.GetData(),
            new someActions.LoadData()
        ])
    )
);
@Effect()
dispatchMultiAction$:Observable=此.actions$.pipe(
类型(someActions.Dispatch),
合并映射(=>[
新建someActions.InitData(),
新建someActions.GetData(),
新建someActions.LoadData()
])
)
);

与xandermonkey的答案类似,但使用正确的运算符:

@Effect()
dispatchMultiAction$: Observable<Action> = this.actions$.pipe(
    ofType<SomeAction.Dispatch>(someActions.Dispatch),
    concatMap(_ => [
            new someActions.InitData(),
            new someActions.GetData(),
            new someActions.LoadData()
        ])
    )
);
@Effect()
dispatchMultiAction$:Observable=此.actions$.pipe(
类型(someActions.Dispatch),
concatMap(=>[
新建someActions.InitData(),
新建someActions.GetData(),
新建someActions.LoadData()
])
)
);

注意concatMap和mergeMap之间的区别。因为concatMap在前一个完成之前不会订阅下一个可观测值,所以将首先发出源延迟2000ms的值。与立即订阅内部观测值的mergeMap相比,延迟较小(1000ms)的观测值将发出,然后是2000ms完成的观测值。

谢谢!因此,我将创建一个接受数组的服务,并对后端进行n次调用以进行更改?让api接受数组的目的是让您可以在一次调用中进行批量更新,而不是往返于服务器。链接到YouTube视频不是一个可接受的答案。评论是可以的,但不是答案。至少解释一下视频中的内容,然后链接到视频作为参考,谢谢你的建议。我改变了答案。我分享了这个链接,因为我认为这是非常重要的视频,以了解ngrx的行动架构。谢谢!这段视频实际上让人大开眼界。我一直在重复使用动作,并且看到了其中的一些陷阱。所以他提到,独特的事件动作会产生更多的动作,但它们也会产生同样多的效果和还原效果,对吗?使用
mergeMap
,这样做更干净。你为什么不使用“of”操作符呢。我不知道它为什么有时被用来调度动作,有时不能。你可以考虑从RealNrxjs中读取。他们对每个操作员都有很好的描述。谢谢。我想我理解of操作符的作用,但我不确定为什么有时动作会像Tony上面显示的那样作为一个可观察对象发送,有时又不像您的示例中那样Tony使用([])的
的唯一原因是因为
switchMap
只返回一个可观察对象。本质上,他所做的是一个返回多个动作的变通方法。但是,使用
mergeMap
可以正确返回多个操作。