angular - 当 reducer 更改切片时,Ngrx 选择器未触发

标签 angular ngrx

我正在开发一个广泛使用 Ngrx 存储的 Angular 2 应用程序。我在我的商店里有一个不错的结构。我使用选择器来检索状态切片,通常所有选择器都会正确触发它们关联的订阅。 Ngrx 是惊人的。

可悲的是,今天我遇到了一个新问题,我尝试在网上四处寻找解决方案,但没有成功。我终于通过测试不同的语法找到了自己的解决方法,但我很好奇为什么会发生这种情况。

这个选择器和我所有的其他选择器一模一样:

export const getToolBars = (state: State): any => state.toolBars;
export const selectState: MemoizedSelector<object, State> = createFeatureSelector<State>('http');
export const selectToolBars: MemoizedSelector<object, any> = createSelector(selectState, getToolBars);

问题是选择器不会像通过 reducer 更新数据时那样触发订阅。

我为这种特殊情况找到了解决方法。使用这个:
export const getToolBars = (state: State): any => { return { toolBars: state.toolBars }; };

代替 :
export const getToolBars = (state: State): any => state.toolBars;

修复它,但我希望我所有的 setter/getter 看起来都一样,所以我想知道为什么这个问题首先会发生?

附加信息,state.toolBars 是一个接口(interface)为的对象
toolBars: { [name: string]: any };

任何提示或引用都可以。现在一切都“有效”我只是在寻找提高我技能的方法。非常感谢你!

编辑:

我做了一个stackblitz来说明这个问题。

https://stackblitz.com/edit/angular-selector-issue?file=src%2Fapp%2Froot-store%2Ftest-store%2Fselectors.ts

在这个 stackblitz 上,每当 reducer 在 toolBars 状态中添加东西时,我都会将日志记录到控制台。每两秒钟,就会向状态添加一个新条目。

在当前状态下,reducer 添加内容时不会触发订阅。

如果在 selectors.ts 中我们注释第 6 行并取消注释第 7 行,它的工作原理与在我的应用程序中一样。我想知道为什么通常的语法不会......

最佳答案

您正在直接修改状态,这就是问题所在。

选择器默认被内存,并检查参数是否在最后一次调用和当前调用之间发生了变化。此检查是一个简单的引用检查 (===)。因为您正在直接修改状态,所以引用保持不变。

要解决此问题,您可以执行以下操作:

return {
        ...state,
        toolBars: {
          ...state.toolBars,
          [action.value]: action.subValue
        }
}

关于angular - 当 reducer 更改切片时,Ngrx 选择器未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53089707/

相关文章:

javascript - 可以设置PipeTransform多个filter

javascript - 如何使用 rxjs 对先前的项目链接多个 .map() 调用

angular - 我的 NgRx 效果不工作,没有任何反应

angular - 从 - "createAction"函数获取类型

javascript - 在间隔上显示和隐藏 Angular Material 工具栏?

angular - 是否需要显式取消订阅组件中的服务?为什么? ( Angular 7)

events - Ionic2 切换组件更改事件未触发

javascript - 类型 'results' 上不存在属性 'AppComponent'

angular - ngrx - 嵌套 reducer

javascript - 在 Angular 中使用 ngrx 时捕获超时错误