SAP Commerce Cloud Spartacus UI 的高阶 reducer 设计

举报
汪子熙 发表于 2022/07/31 23:12:49 2022/07/31
【摘要】 在 components.reducer.ts 里,loaderReducer 函数,会根据输入的 entityType,返回一阶 reducer.然后在代码第86行,调用该一阶 reducer 进行状态转换,返回新的状态。在 cms store reducers index.ts 里,该 reducer 被导入,见代码第21行:然后,在第49行,调用 entityReducer,给 COM...

在 components.reducer.ts 里,loaderReducer 函数,会根据输入的 entityType,返回一阶 reducer.

然后在代码第86行,调用该一阶 reducer 进行状态转换,返回新的状态。

在 cms store reducers index.ts 里,该 reducer 被导入,见代码第21行:

然后,在第49行,调用 entityReducer,给 COMPONENT_ENTITY 类型生产一个新的 reducer 函数。

这个新的 reducer 的函数体:

getReducer 在何时会被调用?

除了 index.ts 之外,其他都是单元测试代码:

通过工厂方法 + injection token 的方式暴露给外部:

最后被导入到 CmsStore module 的 providers 区域里即可:

为了给用户更好的反馈,基于他们的行为,我们经常需要保留诸如“正在加载购物车”、“获取用户地址失败”等信息。 对于每个单独的应用程序状态,我们必须将元数据放在旁边。 分别用于购物车、用户信息、产品数据等。 在所有这些地方手动实现这个逻辑会导致在整个代码库中针对同一问题有不同的解决方案。 这就是在 spartacus 中创建 loaderReducer 的原因。 这个reducer 标准化了整个状态树(state tree)中的元数据处理。 您可以在树的任何深度、任何需要的地方使用它。 除了reducer,我们还提供 actions 和 selectors 的实用程序。

一个例子:

在 app.module.ts 里插入如下代码:

export class AppModule { 
  constructor(private config: DebugConfig,
    private actions$: Actions){
    // console.log('Jerry config: ', this.config);
    this.actions$.pipe(
      ofType(CartActions.LOAD_CART),
      map((action: CartActions.LoadCart) => action.payload),
      tap((data) => console.log('Jerry cart: ' , data))).subscribe();
  }

}

运行时效果:

Error 是经常放置在 NgRx Store 中的 AJAX 调用状态之一。 其他状态包括 Loading,Loaded 和 Success 等等。

interface ResultState {
  result: Result,
  error: string|null,
  isLoading: boolean,
  isLoaded: boolean,
}

为什么将这些状态放入 Store? 嗯,这通常是由用户体验决策驱动的。例如,用户应该能够在等待调用完成时看到某种进度指示器,或者如果调用结果出错时,能看到错误消息。

SAP Spartacus 采用了统一的工具 reducer,名为 loaderReducer,来为 entity 加载添加不同的标志位:

Higher order reducer that adds generic loading flag to chunk of the state. It utilizes “loader” meta field of actions to set specific flags for specific action (LOAD, SUCCESS, FAIL, RESET)

将通用加载标志添加到状态块的高阶 reducer. 它利用“加载程序”元操作字段来设置特定操作的特定标志(加载、成功、失败、重置)

一旦某个 entity 加载成功之后,首先触发高阶 reducer:

注意这行语句:

return Object.assign(Object.assign({}, state), { value: reducer ? reducer(state.value, action) : action.payload, loading: false, error: false, success: true });

显式将 state 里的 loading 字段硬编码为 false.这样无需应用程序手动修改 loading 标志位了。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。