【问题标题】:ngrx createSelector with filter带过滤器的 ngrx createSelector
【发布时间】:2021-05-10 16:33:28
【问题描述】:

我有一个选择器可以获取当前选中的项目:

const getSelectedItem = createSelector(
  getItemId,
  getItemsById,
  (itemId: string, itemsById: Record<string, Item>) => itemsById[itemId],
);

这可行,但我多次使用它,并且在订阅组件时必须应用 filter 运算符,这样底层函数就不会尝试使用尚不存在的项目:

this.store.select(getSelectedItem).pipe(filter(Boolean)).subscribe((item: Item) => {
  // fetch reviews, etc.
  this.store.dispatch(fetchItemReviews({ item }));
});

但是我有很多组件都依赖于同样的逻辑。如何将filter(Boolean) 封装在我的getSelectedItem 中?这是我最接近的,但有时它仍然会发出false

getSelectedItem = createSelector(
  getItemId,
  getItemsById,
  (itemId: string, itemsById: Record<string, Item>) => !!itemsById[itemId] && itemsById[itemId],
);

只是在投影机功能后标记filter(Boolean)也不起作用:

getSelectedItem = createSelector(
  getItemId,
  getItemsById,
  (itemId: string, itemsById: Record<string, Item>) => itemsById[itemId],
  filter(Boolean),
);

【问题讨论】:

  • 您可以添加您的reducer 代码吗?最初认为itemsById应该是状态,在reducer中过滤

标签: angular ngrx ngrx-store


【解决方案1】:

我想出了一些可行的方法:

getSelectedItemRaw = createSelector(
  getItemId,
  getItemsById,
  (itemId: string, itemsById: Record<string, Item>) => itemsById[itemId],
);

getSelectedItem = createSelector(
  select(state => getSelectedItemRaw(state)),
  filter<Item>(Boolean),
);

getSelectedItem的类型是MemoizedSelector&lt;Observable&lt;State&gt;, Observable&lt;Item&gt;&gt;,所以需要在效果/组件中和this.store.pipe(getSelectedItem)一起使用。坏消息是测试很麻烦,我只能通过设置getSelectedItemRaw的值来测试

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 2018-06-19
    • 2018-04-10
    • 2021-04-08
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多