使用 selector 从 SAP Spartacus state 里读取 Cart 数据

选择器 selector 是用于获取存储状态 state 切片的纯函数。

@ngrx/store 提供了一些帮助函数来优化这个选择。 选择器在选择状态切片时提供了许多功能。

使用 createSelector 和 createFeatureSelector 函数时,@ngrx/store 会跟踪调用选择器函数的最新参数,在 ngrx-store.js 里完成。

因为选择器是纯函数,当参数匹配时可以返回最后一个结果,而无需重新调用选择器函数。这可以提供性能优势,特别是对于执行昂贵计算的选择器。这种做法被称为 memoization.

最佳实践:

设计一个 featureState 包含了具体的应用逻辑。使用 createSelector 工具函数创建 selector.

Spartacus 里有类似设计:


看个例子:

export class AppModule { 
  constructor(private config: DebugConfig,
    private actions$: Actions,
    private cartService: ActiveCartService,
    private store: Store){
    // console.log('Jerry config: ', this.config);
    /*const action = this.actions$.pipe(
      ofType(CartActions.LOAD_CART),
      map((action: CartActions.LoadCart) => action.payload),
      tap((data) => console.log('Jerry cart: ' , data)));
      
    action.subscribe();
      
    const action2 = this.actions$.pipe(
      ofType(CartActions.LOAD_CART_SUCCESS),
      map((action: CartActions.LoadCartSuccess) => action.payload),
      tap((data) => console.log('Jerry cart SUCCESS: ' , data)));

    action2.subscribe();*/

    
    const action3 = this.actions$.pipe(
      ofType(CartActions.LOAD_CART_SUCCESS),
      map((action: CartActions.LoadCartsSuccess) => action.payload),
      tap((data) => {
        console.log('Jerry cart SUCCESS: ' , data);
        this.store.pipe(select(MultiCartSelectors.getMultiCartEntities)).subscribe((value) => {
          console.log('Jerry result from selector: ', value);
        });
      }));
    
      action3.subscribe();

      /*
    const loading$ = this.cartService.getLoading();
    
    loading$.subscribe((data) => console.log('Jerry cart loading? ', data));*/
  }
}

运行时:

第一层:entities
第二层:000001
第三层:error,loading,success,processesCount 和 value.

这个 state 的结构是在哪里定义的呢?

在 feature 的 store 文件夹下。

ProcessesLoaderState 提供了 processesCount 字段,它本身又是 LoaderState 类型:


因此也具有了 loading, error, success 和 value 四个字段:


EntityState 接口,本身又提供了第一层的 entities 结构和第二层的 id 结构。

在我写下面这段高亮代码的上下文里,Cart 肯定已经可用了,因为它是在 LOAD_CART_SUCCESS 的回调里执行的。

单步调试:

先执行distinguished,再执行 map:

value 包含了所有的 state 数据:


直接从内存里返回上一次的 result:


强行在调试器里把值改了。

被迫重新执行 projectionFn:

注意,这个强行改值需要进行两次。

首先获得 feature state:


再从 state 里将 carts 数据提取出来:


大功告成:


更多Jerry的原创文章,尽在:"汪子熙":


你可能感兴趣的:(使用 selector 从 SAP Spartacus state 里读取 Cart 数据)