我正在将Angular 7和NgRx一起使用。我创建了一个选择器以使用filter
从存储中获取一些数据,但是当存储中的任何内容发生更改时,即使它与我的选择器无关,此选择器也会发出。
我已经演示了我的问题。这是我的选择器:
export const getMyArrayFilter = createSelector(
getCounterState,
state => state.myArray.filter(x => x === 'new Item')
);
在这里,我正在使用getMyArrayFilter
选择器:
this.store.pipe(select(fromRoot.getMyArrayFilter)).subscribe(x => console.log(x));
但是如上所述,此selector
会在状态发生任何变化时发出。
请看一下this StackBlitz演示。
如果您尝试单击“将项目添加到阵列”或“-”或“ +”按钮,则我的getMyArrayFilter
将发出并每次登录到控制台。如果状态更改为myArray
,我的选择器是否应该仅发出值?
我看了一个this SOF问题,其中提到使用distinctUntilChanged
,但这似乎对我不起作用。
答案 0 :(得分:0)
通过示例进行测试,我只是注意到ngrx通过引用而不是其中的每个项比较数组,这意味着,由于函数过滤器返回带有新引用的新数组,因此ngrx认为这是不同的这就是为什么每次发生更改时都会调用订阅的原因。
创建新副本具有相同的效果:
export const getMyArrayFilter = createSelector(
getCounterState,
state => [ ...state.myArray ]
);
答案 1 :(得分:0)
正如亚历杭德罗(Alejandro)所指出的,这是因为const updateSectionHeadings = () => {
listItems.forEach(item => {
// if the item has the active or current class
if (item.classList.contains('active') || item.classList.contains('current')) {
// set itemData to the data attribute's value
let itemData = item.getAttribute('data-name')
// loop through the section list
innerItems.forEach(innerItem => {
// set innerItemData to the data attribute's value
let innerItemData = innerItem.getAttribute('data-name')
if (itemData !== innerItemData) {
// if itemData is not the same as innerItemData
innerItem.classList.remove('active')
} else if (itemData === innerItemData) {
// if itemData is the same as innerItemData
innerItem.classList.add('active')
}
})
}
})
}
document.addEventListener("scroll", updateSectionHeadings)
window.addEventListener("resize", updateSectionHeadings)
有一个新的参考。
您可以根据需要修改备忘录,Alex Okrushko在他的演讲NgRx: Selectors are more powerful than you think