【问题标题】:NgRx: Passing store value to store selectorNgRx:将存储值传递给存储选择器
【发布时间】:2019-04-28 17:34:53
【问题描述】:

我有一个联赛管理应用 - 带有一个赛季选择器组件,当更改时更新商店中的 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,因此我需要一个选择器来按季节过滤。

【问题讨论】:

  • 如果您已经使用this.store.dispatch(new AllFixturesBySeasonRequested({seasonId: this.seasonId$})); 加载了与您所在州的一个赛季对应的赛程,为什么还要在选择器中再次传递该赛季? select(selectAllFixturesFromSeason) 应该足够了。
  • @BernardPagoaga 因为我想把不同季节的灯具保存在商店里,所以它们不需要再次重新加载,所以需要说明我选择的是哪个季节
  • 如果我将 AllFixturesBySeasonRequested 调度中的 this.seasonId$ 替换为例如数字,我不会收到错误消息,因此我认为问题是将存储变量传递给存储? 那么 this.season$ 的值是多少?按照惯例,它似乎是可观察的?
  • @BernardPagoaga 嗯,是的,实际上我将它作为 Observable 类型,但随后出现编译错误,类型 Observable 不可分配给类型编号,因此我没有指明类型时定义属性

标签: angular rxjs ngrx


【解决方案1】:

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

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

}

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

【讨论】:

  • 太棒了,这要好得多,因为它还会在 seasonId 存储值更改时更新。但是-您对嵌套订阅是什么意思-您的代码不包含任何内容? fixtures$ 正在使用异步管道
猜你喜欢
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 2022-04-21
  • 1970-01-01
相关资源
最近更新 更多