You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NgRx Effects中替换Facade代码?寻求最佳实践方案

解决NgRx Effects中调用Facade的最佳实践问题

问题根源

在NgRx架构里,Facade的核心职责是为组件层封装Store的操作(分发Action + 选择数据),而Effects的作用是监听Action流、处理副作用并触发新的Action。在Effects里调用Facade会打破职责边界,增加模块耦合,还会让Effects的逻辑变得不透明——得深入Facade内部才能知道实际触发了哪些Action。

优化方案:直接在Effects中分发Action

你的Facade方法本质都是调用store$.dispatch()触发对应Action,所以在Effects里可以跳过Facade,直接导入并触发这些Action,既符合NgRx单向数据流设计,又能让逻辑更清晰。

重构后的Effects代码

import * as countListActions from '../../count-list/store/count-list.actions';
import * as countDetailsActions from '../../count-details/store/count-details.actions';
// 其他必要导入...

closeCountSuccess$ = createEffect(() =>
    this.actions$.pipe(
      ofType(CountActions.CountActionTypes.CLOSE_COUNT_SUCCESS),
      switchMap((action: fromActions.CountSuccess) => {
        // 直接分发对应Action,替代Facade调用
        this.store$.dispatch(new countListActions.Reset());
        this.store$.dispatch(new countListActions.SetPageNumber({ pageNumber: 0 }));
        this.store$.dispatch(new countListActions.GetCountListRequest({ page: 0, size: 20 }));
        this.store$.dispatch(new countDetailsActions.SetCurrentCountRequest());
        
        this.openSimpleSnackbar(
          this.translateService.instant('content.count-is-successfully-closed'),
          5000,
          G3SnackType.Success
        );
        return of(new fromActions.WizardCloseDialog());
      })
    )
  );

保留Facade的原有职责

CountFacade依然保留给组件使用,组件通过Facade封装的方法操作Store,确保组件层代码简洁,同时Effects层直接和Store交互,职责更单一:

// Facade代码保持不变,供组件调用
@Injectable({ providedIn: 'root' })
export class CountFacade {
  constructor(private store$: Store<CountState>) {}

  // ...原有方法不变,组件调用这些方法触发Action
  fetchCountList({ page, size }) {
    this.store$.dispatch(new countListActions.GetCountListRequest({ page: page, size: size }));
  }

  resetCountList() {
    this.store$.dispatch(new countListActions.Reset());
  }

  // ...其他方法
}

额外优化建议(可选)

如果想让显示Snackbar这类副作用也遵循Action驱动模式,可以抽成单独的Effect:

  1. 定义ShowSuccessSnackbar Action
  2. 创建监听该Action的Effect,在里面调用openSimpleSnackbar
  3. 在closeCountSuccess$ Effect中分发这个Action,替代直接调用方法

这样所有副作用都通过Action触发,更符合NgRx纯函数、可追踪的设计理念。

内容的提问来源于stack exchange,提问作者robi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:05:27