【问题标题】:How to dispatch multiple actions in ngrx如何在ngrx中调度多个动作
【发布时间】:2020-10-29 09:24:24
【问题描述】:

我有这个效果

loadFirms$ = createEffect(() => {
    return this.actions$
    .pipe(
        ofType(SidebarAction.loadFirmList),
        switchMap((action) =>

          this.sidebarService.getFirms(action.userId).pipe(
           map(firmList => {
               let firms: Firm[] = [];
               Object.keys(firmList).map(value => {
                 let keyArray = value.replace('[', '').replace(']', '').split(', ');

                 firms.push({
                   id: parseInt(keyArray[0]),
                   firmName: keyArray[1],
                   roles: firmList[value]
                 });

          });

          return SidebarAction.loadFirmSuccess({firms});
        }),
      )
    )
    );
});

在 loadFirmList 操作(将 userId 有效负载用作参数)上,我想做一个“getFirms”GET 请求,编辑相关响应(我将一个对象编辑成一个对象数组)并将这个新数组(如有效负载)传递给加载FirmSuccess。这工作正常,但我还需要使用“公司”数组中的属性来进行另一个 http get 调用。我认为最好的方法是像这样调度另一个动作:

loadFirms$ = createEffect(() => {
    return this.actions$
    .pipe(
        ofType(SidebarAction.loadFirmList),
        switchMap((action) =>

          this.sidebarService.getFirms(action.userId).pipe(
           map(firmList => {
               let firms: Firm[] = [];
               Object.keys(firmList).map(value => {
                 let keyArray = value.replace('[', '').replace(']', '').split(', ');

                 firms.push({
                   id: parseInt(keyArray[0]),
                   firmName: keyArray[1],
                   roles: firmList[value]
                 });

          });

          return [SidebarAction.loadFirmSuccess({firms}),SidebarAction.loadDocuments({firms}) ];
        }),
      )
    )
    );
});

关于 loadDocuments 的调度,我将调用另一个 http get 服务:“loadDocuments”。 最好的方法是什么?

【问题讨论】:

  • 您在这里没有 loadFirmFailure 操作,但想象一下您有。然后,您也会在失败时调用 loadDocuments Action。最好的方法是从 loadFirmSuccess 效果中调度 loadDocuments。

标签: angular typescript ngrx


【解决方案1】:

您可以执行以下操作以从一个效果分派多个操作:

switchMap((action) =>
  this.sidebarService.getFirms(action.userId).pipe(
    map(firmList => {
      let firms: Firm[] = [];
      Object.keys(firmList).map(value => {
        let keyArray = value.replace('[', '').replace(']', '').split(', ');

        firms.push({
          id: parseInt(keyArray[0]),
          firmName: keyArray[1],
          roles: firmList[value]
        });
      });
      return firms;
    })
  )
),

// time to dispatch multiple actions
switchMap((firms) => [
  new SidebarAction.loadFirmSuccess({firms}),
  new SidebarAction.loadDocuments({firms})
])

【讨论】:

  • 好的。谢谢你。但什么是“新”?这是为了创建对象吗?动作不是函数?
  • 我的操作是这样的:export const loadFirmSuccess = createAction( '[Sidebar] Load Firm List success', props<{ firms: Firm[] }>() );
  • 通常Action是一个接口,将由类实现。如果你会做“香草”风格,它看起来像export class AddAction implements Action {...}。因此,函数createAction 应该返回一个对象,而不是函数。
【解决方案2】:

移动这一行:

return [SidebarAction.loadFirmSuccess({firms}),SidebarAction.loadDocuments({firms}) ];

在您的 getFirms 地图处理程序内部:

loadFirms$ = createEffect(() => {
    return this.actions$
    .pipe(
        ofType(SidebarAction.loadFirmList),
        switchMap((action) =>

          this.sidebarService.getFirms(action.userId).pipe(
           map(firmList => {
               let firms: Firm[] = [];
               Object.keys(firmList).map(value => {
                 let keyArray = value.replace('[', '').replace(']', '').split(', ');

                 firms.push({
                   id: parseInt(keyArray[0]),
                   firmName: keyArray[1],
                   roles: firmList[value]
                 });
              return [SidebarAction.loadFirmSuccess({firmList}),SidebarAction.loadDocuments({firmList}) ];
          });


        }),
      )
    )
    );
});

你的内部 observable 可以映射到一个 action 数组,或者映射到 action 的 observable 数组。在这种情况下,您将映射到一组操作。

【讨论】:

    猜你喜欢
    • 2020-01-25
    • 2018-11-10
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2019-12-16
    • 1970-01-01
    相关资源
    最近更新 更多