NgRx: селектор вызывается при переходе на другую страницу - PullRequest
1 голос
/ 09 ноября 2019

Я новичок в NgRx. После нескольких чтений я добавил маршрутизатор (@ngrx/router-store) в состояние приложения, чтобы получить доступ к параметру маршрутизатора в селекторе. Я использую CustomRouterSerializer вместе с RouterState.Minimal. С тех пор я сталкиваюсь с проблемой, которая заключается в том, что при переходе от страницы сведений ( / hero /: heroId ) к странице списка ( / ), например, *Вызывается селектор 1008 * со страницы сведений, что приводит к другим проблемам. Конечно, я могу поставить нулевые чеки ...

Но так как я новичок, я подумал, что лучше спросить. Кажется неправильным, что getSelectedHero вызывается при переходе на другую страницу. Конечно, состояние маршрутизатора меняется, но?

Я потратил некоторое время, пытаясь найти решение, которое не включает неопределенную проверку.

Я создал «супер» приложение, которое демонстрирует проблему,Я поднял его до GitHub и до StackBlitz .

Вот код селектора со страницы сведений ( / 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));
}

1 Ответ

1 голос
/ 09 ноября 2019

Проблема в том, что при переходе к другим маршрутам параметр маршрута :heroId недоступен.

при переходе на страницу героя, например .../hero/2, параметр маршрута :heroIdдоступно, потому что вы определили маршрут hero/:heroId;

Когда вы переходите на корневую страницу .../, маршрут соответствует "", и это приводит к тому, что параметр маршрута :heroId не устанавливается (этона вашем селекторе отображается как неопределенное)

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

Поскольку ваш getSelectedHero использует селектор селектора состояния маршрута getRouteState, каждый раз, когда происходит изменение маршрута и активна подписка под hero$, getSelectedHero будет называться.

для разрешения вы можете сделать:

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

Или вы можете переместить выбранную переменную heroId в состояние героя, таким образом навигация не вызывает выбор данных героя

...