[英]React to nested state change in Angular and NgRx
Please consider the example below 请考虑以下示例
// Example state
let exampleState = {
counter: 0;
modules: {
authentication: Object,
geotools: Object
};
};
class MyAppComponent {
counter: Observable<number>;
constructor(private store: Store<AppState>){
this.counter = store.select('counter');
}
}
Here in the MyAppComponent
we react on changes that occur to the counter
property of the state. 在MyAppComponent
我们对状态的counter
属性发生的更改做出反应。 But what if we want to react on nested properties of the state, for example modules.geotools
? 但是如果我们想对状态的嵌套属性做出反应 ,例如modules.geotools
呢? Seems like there should be a possibility to call a store.select('modules.geotools')
, as putting everything on the first level of the global state seems not to be good for overall state structure. 似乎应该有可能调用store.select('modules.geotools')
,因为将所有内容放在全局状态的第一级似乎不利于整体状态结构。
Update 更新
The answer by @cartant is surely correct, but the NgRx version that is used in the Angular 5 requires a little bit different way of state querying. @cartant的答案肯定是正确的,但Angular 5中使用的NgRx版本需要一些不同的状态查询方式。 The idea is that we can not just provide the key to the store.select()
call, we need to provide a function that returns the specific state branch. 我们的想法是,我们不能只提供store.select()
调用的密钥,我们需要提供一个返回特定状态分支的函数 。 Let us call it the stateGetter and write it to accept any number of arguments (ie depth of querying). 让我们将其称为stateGetter并将其写入以接受任意数量的参数(即查询深度)。
// The stateGetter implementation
const getUnderlyingProperty = (currentStateLevel, properties: Array<any>) => {
if (properties.length === 0) {
throw 'Unable to get the underlying property';
} else if (properties.length === 1) {
const key = properties.shift();
return currentStateLevel[key];
} else {
const key = properties.shift();
return getUnderlyingProperty(currentStateLevel[key], properties);
}
}
export const stateGetter = (...args) => {
return (state: AppState) => {
let argsCopy = args.slice();
return getUnderlyingProperty(state['state'], argsCopy);
};
};
// Using the stateGetter
...
store.select(storeGetter('root', 'bigbranch', 'mediumbranch', 'smallbranch', 'leaf')).subscribe(data => {});
...
select
将嵌套键作为单独的字符串,因此您的select
调用应该是:
store.select('modules', 'geotools')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.