NgRx和RxJS:从属状态选择器

时间:2020-02-12 04:11:29

标签: angular rxjs ngrx ngrx-store switchmap

我有一个可以在构造函数中订阅多个状态片的组件。

 @ViewChild(PComponent) PGrid: PComponent;

ngOnInit() {
    this.store.pipe(
          select(fromReports.getProcessState),
          takeWhile(() => this.componentActive))
          .subscribe(selectedProcess=> {
            if (selectedProcess) {
              this.Data= selectedProcess.Data;
  }
          });

  this.store.pipe(
          select(fromReports.getProcessAnalysis),
          takeWhile(() => this.componentActive))
          .subscribe(analysisData => {
            if (analysisData) {
              this.PGrid.LoadData(analysisData);
              }
          });
}

第一个订阅订阅一个对象数组,而第二个订阅调用另一个组件(@ViewChild(PComponent)PGrid)中的方法。 LoadData()组件中的PGrid方法取决于第一个订阅中的this.Data。

运行代码时,我对此没有定义。数据尽管有selectedProcess.Data有价值

this.store.pipe(
          select(fromReports.getProcessState),
          takeWhile(() => this.componentActive))
          .subscribe(selectedProcess=> {
            if (selectedProcess) {
              this.Data= selectedProcess.Data; //undefined

  }
          });

这意味着当订阅状态的第二个片段并调用LoadData()方法时,由于未定义this.Data,因此会出错。

我相信这是由于Observable的工作方式所致,并且由于它们是异步的,因此一个函数可能不会在另一个函数之前返回值。

Que:1为什么this.Data= selectedProcess.Data;设置this.Data为undefined,即使selectedProcess.Data有值

问题2:我看过flatMapswitchMap,但是由于我是RxJS和NgRx的新手,所以我对如何利用它们感到困惑。有提示吗?

P.S类似地,我在ngOnInit()中分别订购了2个切片,这是首选方法还是应该将它们组合在一起?

1 个答案:

答案 0 :(得分:1)

一切都是流。

每个可观察的流都应以$命名。

避免使用订阅直到结束。

combineLatest将不会发出初始值,直到每个可观察对象发出至少一个值为止。

tap可用于副作用和记录,并且不影响流。 “我不知道我在做什么” 。我使用它很随意。

伪代码

import { of, combineLatest } from "rxjs";
import { map, delay, tap, switchMap } from "rxjs/operators";

const DATA = "selectedProcessData";
const PROCESS_ANALYSIS = "analysis";

const service = {
  getData: () => {
    return of(DATA).pipe(delay(2000));
  },
  loadData: data => {
    return of(data).pipe(delay(2000));
  }
};
const store = {
  getProcessAnalysis: () => {
    return of(PROCESS_ANALYSIS).pipe(delay(2000));
  }
};

let getSelectedProcessData = null;
const getSelectedProcessData$ = service.getData().pipe(
  tap(data => console.log(`getSelectedProcessData::${data}`)),
  tap(data => (getSelectedProcessData = data))
); // mimick getting data from a service

const getAnalysisData$ = store.getProcessAnalysis(); // mimick selection of state

const loadAnalysisData$ = combineLatest(
  getSelectedProcessData$,
  getAnalysisData$
).pipe(
  tap(([getSelectedProcessData, getAnalysisData]) =>
    console.log(`combineLatest::${getSelectedProcessData}, ${getAnalysisData}`)
  ),
  map(([getSelectedProcessData, getAnalysisData]) => getAnalysisData),
  switchMap(getAnalysisData => service.loadData(getAnalysisData))
);

loadAnalysisData$.subscribe(loadedAnalysisData =>
  console.log(`loadedAnalysisData::${loadedAnalysisData}`)
);

Stackblitz

相关问题