对Angular和NgRx中的嵌套状态变化做出反应

Ale*_*lov 3 javascript ngrx angular ngrx-store

请考虑以下示例

// 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');
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,MyAppComponent我们对counter状态属性发生的变化做出反应。但是,例如,如果我们想对状态的嵌套属性做出反应modules.geotools怎么办?似乎应该可以调用a store.select('modules.geotools'),因为将所有内容置于全局状态的第一层似乎对整体状态结构不利。

更新资料

@cartant的答案肯定是正确的,但是在Angular 5中使用的NgRx版本需要一些不同的状态查询方式。这个想法是,我们不能只提供store.select()调用的键,我们需要提供一个返回特定状态分支的函数。让我们将其称为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 => {});
...
Run Code Online (Sandbox Code Playgroud)

car*_*ant 5

select将嵌套键作为单独的字符串,因此您的select调用应为:

store.select('modules', 'geotools')
Run Code Online (Sandbox Code Playgroud)