当状态发生任何变化/选择器无法正常运行时,NgRx选择器就会发出信号

时间:2019-07-18 12:28:12

标签: javascript angular rxjs ngrx

我正在将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,但这似乎对我不起作用。

2 个答案:

答案 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

中做到了这一点。

enter image description here

enter image description here