NgRx:选择多个属性

时间:2018-12-18 02:10:48

标签: angular redux ngrx

我有一个保存在商店中的对象,我想订阅以监听一些属性。

我正在使用NgRx 6.1.2,但对于如何监听某些状态属性(包括嵌套属性)的变化,我还有很多疑问。

我的意图是使用两个属性来验证加载数据是否已完成,而使用另一个属性来填充组件变量并呈现组件,

我写了这个,但是没有用,因为它监听整个商店的变化,而不是选择的属性。

this.isLoading = true;
this.inicioSubs = this.store
.pipe(
  select(state => {
    return {
      temas: state.multimedia.multimedia.temas,
      series: state.multimedia.multimedia.series,
      lastSerie: state.multimedia.multimedia.lastSerie,
      lastTwoYearsSeries: state.multimedia.multimedia.lastTwoYearsSeries,
      lastTwoYearsTemas: state.multimedia.multimedia.lastTwoYearsTemas,
      loaded: state.multimedia.loaded,
      loading: state.multimedia.loading
    };
  }),
  filter(multimedia => multimedia.loaded && !multimedia.loading)
)
.subscribe(state => {
  this.multimedia = {
    temas: state.temas,
    series: state.series,
    lastSerie: state.lastSerie,
    lastTwoYearsSeries: state.lastTwoYearsSeries,
    lastTwoYearsTemas: state.lastTwoYearsTemas
  };

  this.isLoading = false;
});

1 个答案:

答案 0 :(得分:1)

您可以编写如下选择器:

export const getMultimedia = (state: AppState) => state.multimedia;
export const getMultimedia = createSelector(
    getMultimediaState,
    multimediaState => multimedia.loading
  );

或者如果您正在使用这样的root状态进行初始化

StoreModule.forFeature('multimedia', reducers);

然后您的multimedia.selectors.ts文件应如下所示:

  export const getMultimediaState createFeatureSelector<MultimediaState>('multimedia');

  export const getMultimedia = createSelector(
    getMultimediaState,
    multimediaState => multimedia.loading
  );

  export const getLoadedMultimedia = createSelector(
    getMultimediaState,
    multimediaState => multimediaState.filter(
      multimedia => multimedia.loaded && !multimedia.loading)
    );

使用createFeatureSelector,您可以返回顶级功能状态。

然后,在您的组件文件中像这样订阅选择器:

   public loadedMultimedia$;
   public isMultimediaLoading$;

   constructor(store) {
     this.loadedMultimedia$ = store.pipe(select(getLoadedMultimedia));
     this.isMultimediaLoading$ = store.pipe(select(getMultimediaLoadingStatus));
   }