SAP Commerce Cloud Spartacus UI 的高阶 reducer 设计
在 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 标志位了。
- 点赞
- 收藏
- 关注作者
评论(0)