0

我的标准化 ngrx 商店如下所示:

export interface State {
    carts: EntityState<Cart>;
    items: EntityState<Item>;
}

export interface Cart {
    id: number;
    maxVolume: number;
}

export interface Item {
    id: number;
    cartId: number;
    volume: number;
}

这是一个非常基本的设置,其中一个购物车可以包含多个项目。我的选择器需要返回一个包含所有购物车的数组,其中包含包含其项目的数组,但还要计算项目是否有从各自购物车中退出的危险:

export const select: MemoizedSelector<object, any> = createSelector(
  selectAllCarts, selectAllItems, 
  (allCarts: Cart[], allItems: Item[]) => {
    return allCarts.map(c => {
      const items = allItems.filter(i => i.cartId == i.id);
      return {
        id: c.id,
        items: items.map(i => {
          // computations, should not run if cart's items have not changed
          // needs to be memoized
          const computed = isCartOverfilled(i, c, items);
          return {
            id: i.id,
            mightFallOut: computed//computed value needs to be output
          }
        })
      }
    });
});

每次更新商品时,isCartOverfilled都会为商店中的每个商品运行。但是,isCartOverfill可能很昂贵,并且仅取决于购物车中的物品。当一个项目更新时,例如被添加到购物车,isCartOverfill应该对里面的项目执行,即由购物车 id 记忆。

我如何实现这一目标?

我试过从一个购物车中选择物品:

export const selectCart = (cartId: number) => createSelector(
  selectItemsByCartId(cartId), selectCartById(cartId),
  (items: Item[], cart: Cart) => {
  return {
    id: cart.id,
    items: items.map(i => {
      const computed = isCartOverfilled(i, cart, items);
      return {
        id: i.id,
        mightFallOut: computed
      }
    })
  }
});

这个选择器不会过度计算,但我需要所有的购物车,我不确定它是否可以使用选择器。

4

1 回答 1

0

由于状态已经改变,选择器将重新计算。

但是您可以使用为购物车保持另一个状态来实现,并且当您调度 addCart Item 操作时,您可以使用单个项目而不是使用 selector 来更新购物车

export interface State {
    carts: EntityState<Cart>;
    cartOverFilled: SomeState or part of Cart State <---
    items: EntityState<Item>;
}

或者

export interface State {
    carts: EntityState<CartState>;
    items: EntityState<Item>;
}

export interface CartState {
    cart: Cart;
    overFilled: any
}

export interface Cart {
    id: number;
    maxVolume: number;
}
  1. 添加一个带有值的状态以检查是否过满;
  2. 为 ofType '添加到购物车'创建一个效果
  3. 创建另一个操作以重新计算现有状态的过度填充传入项目。
于 2019-01-03T14:52:34.153 回答