1

我是 NgRx 的新手。看了一堆之后,我@ngrx/router-store在app状态中添加了router(),来访问selector中的router参数。我正在使用 aCustomRouterSerializerRouterState.Minimal。从那时起,我遇到了一个问题,例如,当我从详细信息页面 ( /hero/:heroId ) 导航到列表页面 ( / ) 时, getSelectedHero详细信息页面的选择器被调用,这会导致其他问题。当然,我可以将空检查放入...

但由于我是初学者,我想我最好问一下。getSelectedHero在转换到不同页面时调用似乎是错误的 。确定路由器状态正在改变,但是?

我花了一些时间试图找到一个不包含未定义检查的解决方案。

我创建了一个演示该问题的“超级”应用程序。我将它推送到GitHubStackBlitz

这是详细页面 ( /hero/:heroId ) 中的选择器代码,当您离开它时会调用该代码。

export const getSelectedHero = createSelector(
  selectHeroesState,
  getRouteState,
  (state, router) => {
    const hero = state.entities[router.state.params.heroId];
    // FixMe: simplifies the problem... hero is undefined if you navigation for /hero/:heroId to / and following line will throw an error.
    console.log("getSelectedHero", hero, hero.id, hero.name); 
    return hero;
  }
);

在详细信息页面 (/hero/:heroId) 我使用以下内容:    

public ngOnInit() {
  this.hero$ = this.store.pipe(select(getSelectedHero));
}
4

1 回答 1

1

问题是当您导航到其他路线时,路线参数:heroId不可用。

例如,当您导航到英雄页面时,.../hero/2路由参数:heroId可用,因为您已经定义了路由hero/:heroId

.../当您导航到路由匹配的根页面""时,这会导致未设置路由参数 :heroId(它在您的选择器上显示为未定义)

const hero = state.entities[router.state.params.heroId]; // <-- here "router.state.params.heroId" is undefined

因为您getSelectedHero使用 selector 路由状态选择器getRouteState,所以每次有路由更改并且订阅处于hero$活动状态时,getSelectedHero都会调用 。

要解决你可以这样做:

if (router.state.params.heroId === undefined) return {};

或者您可以将选定的 heroId 变量移动到英雄状态,这样导航不会触发英雄数据选择

于 2019-11-09T06:13:32.867 回答