首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ngrx/effect (redux-observable)中分派多个动作?

如何在ngrx/effect (redux-observable)中分派多个动作?
EN

Stack Overflow用户
提问于 2018-06-01 00:58:54
回答 2查看 19.7K关注 0票数 12

我使用的是Angular 6,ngrx/store。我有这样的效果,负责更新东西。根据一些逻辑,我想分派不同的动作。如果我使用switchMap安装map ?

这就是我尝试过的,但它不起作用:

代码语言:javascript
复制
@Effect()
  dispathMultipleActions$ = this.actions$.pipe(
    ofType(ActionTypes.UpdateSomething),
    map(() => {
      const actions: Action[] = [];
      const array = [1, 2, 3, 4, 5];
      array.forEach(item => {
        if (item > 3) {
          actions.push(new DeleteAction(item));
        } else {
          actions.push(new ChangeAction(item));
        }
      });
      return actions;
    })
  );
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-01 03:16:44

效果转换动作流,因此您有一个动作流作为输入和输出。在您的示例中,您将操作映射到操作数组。操作数组流不是有效的输出类型。您需要扁平化该数组,这意味着您不会将数组本身发送到输出流中,而是将其每个元素发送到输出流中。

而不是:

代码语言:javascript
复制
input:  --a-------a------>
output: --[b,c]---[b,c]-->

您应该执行以下操作:

代码语言:javascript
复制
input:  --a-------a------>
output: --b-c-----b-c-->

要将数组的可观测值展平为每个元素的可观测值,可以使用以下运算符之一

mergeMap, switchMap, exhaustMap。在大多数情况下,

mergeMap将是正确的选择。如果您想了解有关这些运算符的更多信息,请查看以下内容answer.

代码语言:javascript
复制
@Effect()
register$: Observable = this.actions$.pipe(
  ofType(AuthActionTypes.REGISTER_REQUEST),
  mergeMap((action: RegisterRequest) => {
    // check for register request success
    return [
      new RegisterSuccess(),
      new LoginRequest(action.payload)
    ]
  })
);
票数 36
EN

Stack Overflow用户

发布于 2021-02-25 00:20:00

我也遇到过同样的情况(假设NgRx 10或更高版本),我有一个不同的视角,更基本的使用效果的方式。在一个地方顺序地触发多个动作,特别是在一个单一的效果中,是反模式的。在本质上,保持一致是很重要的

general flow of application state in NgRx

行动和潜力的减少。正如NgRx架构所预见的那样。

下面the 3 effect rules将有助于避免困难的情况:

Name effects作为效果的名称

让你的效果只做一件事仅发出一个操作这样,它可以帮助您遵循设计separation of concerns模式,当然,它也可以帮助你的NgRx效果变得更具单元可测试性。

回到你的例子,你可以简单地解耦你想要做的事情(两个额外的动作)与一个代理之间的动作。在你的情况下,你可能甚至不需要你原来的效dispathMultipleActions$

,除非出现内部的特殊逻辑。(也许,它可能属于状态Reducer,它甚至更具单元可测试性)。

假设ActionTypes.UpdateSomething已经有一个数组负载对象,您可以将您的

dispathMultipleActions$

转换成单个,所以你可以这样做:

代码语言:javascript
复制
@Effect()
deleteAction$ = this.actions$.pipe(
    ofType(ActionTypes.UpdateSomething),
    concatMap(from(new Promise((array) => {
        array.forEach(item => {
            if (item > 3) {
                //do something
            }
        });
    }))),
    {dispatch: false}
);

@Effect()
changeAction$ = this.actions$.pipe(
    ofType(ActionTypes.UpdateSomething),
    concatMap(from(new Promise((array) => {
        array.forEach(item => {
            if (item <= 3) {
                //do something
            }
        });
    }))),
    {dispatch: false}
);
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50629328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档