为什么商店的状态变化没有广播到我的组件中

问题描述 投票:0回答:1

当在组件中调用onMetaSignalChanged()时,它会导致一个效果,该效果又会调用化简器情况rangeSchemasLoadCompletedSuccess。到目前为止,我已经调试了该应用程序并正常工作。如您所见,rangeSchemasLoadCompletedSuccess正在更新存储状态的rangeSchemas,所以我认为我的rangeSchemas $ observable应该在此之后获得更新的值?但是它没有被更新,我缺少什么吗?

模型类别:

export interface RangeSchemaViewModel {
 id: number;
 rangeSchemaName: string;
}

在我的组件中,我将存储状态选择为:

export class MyComponent implements OnInit, OnDestroy {
  rangeSchemas$: Observable<RangeSchemaViewModel[]>;

  ngOnInit() {
    this.rangeSchemas$ = this.store.pipe(
      select(RawSignalsStoreSelectors.selectRangeSchemasViewModel)
    );
  }

   onMetaSignalChanged(event: any) {
     this.store.dispatch(
       RawSignalsStoreActions.changeMetaSignal({ id: event.meta_Signal_Id })
     );
   }

  //onmetaSignalChanged, Action is called which is updating the state of rangeSchemas$
}

这是我的选择器代码:

const getRangeSchemas = (state: State): RangeSchema[] => state.rangeSchemas;

export const selectRangeSchemasState: MemoizedSelector<
  object,
  State
> = createFeatureSelector<State>('raw-signals');

export const selectRangeSchemasViewModel: MemoizedSelector< 
  object,
  RangeSchemaViewModel[]
> = createSelector(
    selectRangeSchemasState,
    getRangeSchemas,
    (state, rangeSchemas) => {
        return rangeSchemas.map((item) =>{
            let rangeSchemaViewModel: RangeSchemaViewModel;
            rangeSchemaViewModel.id= item.mapping.id;
            rangeSchemaViewModel.rangeSchemaName= item.mapping.rangeSchemaName;
            return rangeSchemaViewModel;
        })
    });

减速器代码:

on(rawSignalsActions.changeMetaSignal, (state, { id }) => ({
...state,
linkedMetaSignal: state.metaSignals.filter(item => item.id === id)[0]
 })),
on(rawSignalsActions.rangeSchemasLoadCompletedError, state => ({
    ...state,
    loading: { ...state.loading, rangeSchemas: false }
 })),
on(rawSignalsActions.rangeSchemasLoadCompletedSuccess,
    // tslint:disable-next-line: no-shadowed-variable
    (state, { rangeSchemas }) => ({
      ...state,
      rangeSchemas,
      loading: { ...state.loading, rangeSchemas: false }
    })
  )

效果代码:

  getRangeSchemas$ = createEffect(() =>
  this.actions$.pipe(
      ofType(RawSignalsActions.changeMetaSignal),
      concatMap(action => this.rawSignalsDataService.getRangeSchemas(action.id).pipe(
        map(rs1 => this.constructSignalCounts(rs1)),
        map(rs2 => RawSignalsActions.rangeSchemasLoadCompletedSuccess( { rangeSchemas: rs2 })),
          catchError(err => of(RawSignalsActions.rangeSchemasLoadCompletedError({ error: err })))
      )),
  ));

  constructSignalCounts = ( rangeSchemas: RangeSchema[]) => {
    for (var rangeSchema of rangeSchemas){
        let signalCounts: SignalCount[] = [];
        for (var abstractSignal of rangeSchema.abstractSignals) {
            let signalCount: SignalCount = { range: "0", populationSize: 0, populationPerc: 0, lowRange: 0, highRange:0 };
            signalCount.range = abstractSignal.abstractSignal.name;
            signalCount.populationSize = 20;
            signalCount.populationPerc = 40;
            if (rangeSchema.mapping.type == 2) {    // 2 -> numeric, 3 -> Text
              // actually type will come from Signal Range Schema
              signalCount.lowRange = abstractSignal.numericMappings[0].minValue;
              signalCount.highRange = abstractSignal.numericMappings[0].maxValue;
            }
            signalCounts.push(signalCount);
          }
          rangeSchema.signalCounts = signalCounts;

    }
    return rangeSchemas;
  };
angular typescript ngrx typescript2.0 ngrx-store
1个回答
0
投票

经过将近2天的奋斗,我找到了答案!这是解决问题的选择器代码:

export const selectRangeSchemasState: MemoizedSelector<
  object,
  State
> = createFeatureSelector<State>('raw-signals');

const getRangeSchemas = (state: State): RangeSchema[] => state.rangeSchemas;

export const selectRangeSchemasViewModel: MemoizedSelector<
object,
  RangeSchemaViewModel[]
> = createSelector(
  selectRangeSchemasState,
  getRangeSchemas,
  (state, rangeSchemas) => {
    return state.rangeSchemas.map(item => {
      let rangeSchemaViewModel: RangeSchemaViewModel = {
        id: 0,
        rangeSchemaName: ''
      };
      rangeSchemaViewModel.id = item.mapping.id;
      rangeSchemaViewModel.rangeSchemaName = item.mapping.rangeSchemaName;
      return rangeSchemaViewModel;
    });
  }
);

出现问题的原因如下:

它是应该从其构造视图模型的全局状态,即

return state.rangeSchemas.map(item => {...

rangeSchemaViewModel变量未定义,所以我使用默认值实例化了它。

let rangeSchemaViewModel: RangeSchemaViewModel = {
    id: 0,
    rangeSchemaName: ''
  };
© www.soinside.com 2019 - 2024. All rights reserved.