我正在开发一个广泛使用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);
问题在于,当通过化简器更新数据时,选择器不会像应有的那样触发订阅。
我找到了解决此特定情况的方法。使用这个:
export const getToolBars = (state: State): any => { return { toolBars: state.toolBars }; };
代替:
export const getToolBars = (state: State): any => state.toolBars;
解决了这个问题,但我希望所有的吸气剂看起来都一样,所以我想知道为什么这个问题首先发生?
其他信息,state.toolBars是一个接口为
的对象toolBars: { [name: string]: any };
任何提示或引用都可以。现在一切都“正常”,我只是在寻找提高技能的方法。非常感谢你!
编辑:
我进行了一次闪电战以说明问题。
在这次堆叠闪电战中,我通过reducer将日志添加到控制台,以便在toolBars状态下添加内容。每两秒钟就会向该状态添加一个新条目。
在当前状态下,当reducer添加内容时不会触发订阅。
如果在selectors.ts中,我们注释了第6行,而注释了第7行,则其作用与我的应用程序相同。而且我想知道为什么普通语法不会...
答案 0 :(得分:2)
您正在直接修改状态,这就是问题所在。
默认情况下会记住选择器,并检查参数是否在上次调用和当前调用之间更改。此检查是简单的参考检查(===
)。因为您是直接修改状态,所以引用保持不变。
要解决此问题,您可以执行以下操作:
return {
...state,
toolBars: {
...state.toolBars,
[action.value]: action.subValue
}
}