NgRx:将商店值传递给商店选择器

时间:2019-04-28 17:34:54

标签: angular rxjs ngrx

我有一个联赛管理应用程序-带有季节选择器组件,该组件在更改后会更新商店中的SeasonState.currentlySelectedSeasonId。

在我的灯具组件中,我想使用seasonId传递给选择器以获取该季节的灯具。

但是,出现以下错误(我正在使用NgRx Store Freeze),这似乎表明我正在直接改变状态。

ERROR TypeError: Cannot assign to read only property 'active' of object '[object Object]'

fixture.component.ts

ngOnInit() {
    this.seasonId$ = this.store
        .pipe(
            select(selectCurrentlySelectedSeason)
        ).subscribe();

    this.store.dispatch(new AllFixturesBySeasonRequested({seasonId: this.seasonId$}));
    this.fixtures$ = this.store
        .pipe(
            select(selectAllFixturesFromSeason(this.seasonId$))
        );
  }

如果我用数字将AllFixturesBySeasonRequested的派发中的this.seasonId $替换为数字,我不会收到错误,因此我认为问题是将商店变量传递给商店了吗?

fixture.selectors.ts

export const selectAllFixtures = createSelector(
    selectFixturesState,
    fromFixture.selectAll
);

export const selectAllFixturesFromSeason = (seasonId: number) => createSelector(
    selectAllFixtures,
    fixtures => {
        return fixtures.
            filter(fixture => fixture.seasonId === seasonId);
    }
);

其他相关代码:

fixture.actions.ts

export class AllFixturesBySeasonRequested implements Action {
    readonly type = FixtureActionTypes.AllFixturesBySeasonRequested;
    constructor(public payload: { seasonId: number }) {}
}

fixture.effects.ts

@Effect()
  loadFixturesBySeason$ = this.actions$
      .pipe(
          ofType<AllFixturesBySeasonRequested>(FixtureActionTypes.AllFixturesBySeasonRequested),
          mergeMap(({payload}) => this.fixtureService.getFixturesBySeason(payload.seasonId)),
          map((fixtures) => new AllFixturesBySeasonLoaded({fixtures}))
      );

有关架构的更多信息 我正在尝试实施一种商店解决方案,其中固定装置(结果,团队等也是如此)仅按季节加载,而不是从所有季节获取所有信息。然后应将它们保存在商店中,以免再次需要它们时避免进一步的API调用,因此我需要一个选择器来按季节进行过滤。

1 个答案:

答案 0 :(得分:2)

您应该在操作中传递一个数字,而不是一个可观察的数字,例如:

ngOnInit() {
    this.store
    .pipe(
        select(selectCurrentlySelectedSeason)
    ).subscribe(seasonId => {
        this.store.dispatch(new AllFixturesBySeasonRequested({seasonId}));
        this.fixtures$ = this.store
        .pipe(
             select(selectAllFixturesFromSeason(seasonId))
         );
    });

}

如果需要,您可能需要使用switchMap以避免嵌套订阅。