Ngrx通过调用通用操作来完成效果。

huangapple go评论58阅读模式
英文:

Ngrx finalise effect by calling common action

问题

这是代码部分,不需要翻译:

fetchDealById$ = createEffect(() =>
  this.actions$.pipe(
    ofType(DealsApiActions.fetchDealById),
    concatLatestFrom(() => this.store.select(selectDeals)),
    switchMap(([action, deals]) => {
      const dealFound = deals.find(x => x.id === action.id);
      if (dealFound != undefined) return [
        DealsApiActions.setCurrentDeal({ currentDeal: dealFound }),
        DealsApiActions.setLoading({ loadingDeals: false })
      ];

      return this.dealsService.fetchDealById(action.id).pipe(
        switchMap((dealResponse: any) => [
          DealsApiActions.setCurrentDeal({ currentDeal: dealResponse.data }),
          DealsApiActions.setLoading({ loadingDeals: false })
        ])
      )
    }),
  )
);

你想要翻译的部分如下:

"Is there a cleaner way I can deal with common actions at the end of an effect which may or may not have N delay?"

英文:

I've got an application using NGRX as state management and I've got an effect which looks at the state to find an object by id, and calls the server if it fails. Both of these set the current object in the state, but I also have a loading indicator that I want the effect to handle - as if it has to call the server, there will be a delay.

I've setup my effect like this, which works:

  fetchDealById$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DealsApiActions.fetchDealById),
      concatLatestFrom(() => this.store.select(selectDeals)),
      switchMap(([action, deals]) => {
        const dealFound = deals.find(x => x.id === action.id);
        if (dealFound != undefined) return [
          DealsApiActions.setCurrentDeal({ currentDeal: dealFound }),
          DealsApiActions.setLoading({ loadingDeals: false })
        ];

        return this.dealsService.fetchDealById(action.id).pipe(
          switchMap((dealResponse: any) => [
            DealsApiActions.setCurrentDeal({ currentDeal: dealResponse.data }),
            DealsApiActions.setLoading({ loadingDeals: false })
          ])
        )
      }),
    )
  );

However I'm not happy with calling setLoading twice. I tried adding finalize(() => DealsApiActions.setLoading({ loadingDeals: false }) (also with this.store.dispatch()) but it doesn't seem to fire the action.

Is there a cleaner way I can deal with common actions at the end of an effect which may or may not have N delay?

答案1

得分: 1

不需要两个操作来完成这个任务。相反,使用 DealsApiActions.setCurrentDeal 来同时将 loadingDeals 设置为 false。

你可以将一个操作视为一个事件(加载当前交易),该事件可以触发多个 reducer/effects。我假设加载指示器和交易都在同一个 reducer 中,所以你可以一次性设置交易并设置加载指示器。

英文:

You don't need two actions for this.
Instead, use DealsApiActions.setCurrentDeal to also set loadingDeals to false.

You can see an action as an event (loaded current deals), and the event can trigger multiple reducers/effects. I assume the loading indicator and the deal live in the same reducer, so you can set the deal, and also set the loading indicator in one go.

huangapple
  • 本文由 发表于 2023年2月6日 17:51:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75359711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定