所以在我的组件中我有:
constructor(private store: Store, private basketStore: Store<{ basket: Photo[] }>) { }
position$! :Observable<number>;
RemoveFromBasket(photo: Photo) {
this.position$ = this.basketStore.select(basketPosition(photo.id));
this.basketStore.dispatch(getBasket({ id: this.position$}));
}
我在发送到 getBasket 的 id 参数下收到一条红线,说明
type observable<number> isn't assignable to number
.
我的篮子位置选择器看起来像:
export interface basketSelection {
basket: Photo[];
}
export const selectPosition = (state: basketSelection) => state.basket;
export const basketPosition = (id: number) => createSelector(selectPosition,
(basket: Array<Photo>) => { return basket.findIndex(m => m.id == id) }
)
我的减速机:
on(getBasket, (state, { id }) => state.slice(id)
**** 更新 *****
使用@nate-kumar 回答。
我的篮子里有:
你可以看到我有 2 个 id 为 5 的项目。当我选择删除其中一个 id 为 5 的项目时。(photo.id = 5) 当我从
RemoveFromBasket
功能中出来时,我的状态现在看起来像:
所以 Slice 似乎已经删除了前 2 个项目,因为第一张 ID 为 5 的照片位于位置 2。我将切片更改为
state.slice(id,1)
但这只是从篮子中删除了所有内容。
订阅您的可观察对象以在可观察对象发出值时分派操作。
this.position$ = this.basketStore.select(basketPosition(photo.id));
this.position$
.pipe(
take(1) // Unsubscribes after 1 emission, which works perfectly with click events, where you want to trigger an action only once
)
.subscribe(
(id: number) => {
this.basketStore.dispatch(getBasket({ id }));
}
)
您可以设计这是一种更好的方式,组件不需要也不应该包含所有这些逻辑。
你只想通过动作在组件中说“做这个”,reducer 应该把剩下的整理出来。
这也避免了手动
subscribe
和rxjs逻辑。
//Action
const removeBasket = createAction('Remove Basket', props<id: string>());
...
// Component
removeFromBasket(photo: Photo) {
this.store.dispatch(removeBasket({ id: photo.id });
}
...
// Reducer
on(getBasket, (state, { id }) => state.filter(item => item.id !== id)
// or whatever you want to do with basketPosition(..)