Мой нормализованный магазин 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 будет запускаться для каждого элемента в магазине. Но isCartOverfilled потенциально дорогой и зависит только от товаров внутри корзины. Когда элемент обновляется, например, добавляется в корзину, isCartOverfilled должен выполнить ТОЛЬКО для элементов внутри, т.е. запомнено идентификатором корзины.
Как мне этого добиться?
Я пытался выбрать товары из одной корзины:
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
}
})
}
});
Этот селектор не будет чрезмерно вычислять, но мне нужны все тележки, и я не уверен, выполнимо ли это с селектором.