Угловой дочерний маршрут не обновляется при изменении подпути

Работая над моей работой — вместе с учебником Angular «Tour of Heroes», я пытаюсь увидеть, как работают дочерние маршруты. У меня есть HeroesComponent со встроенным <router-outlet></router-outlet>. HeroesComponent, доступ к которому осуществляется через «/heroes», отображает список ссылок для отдельных героев, для каждой из которых routerLink установлено значение «/heroes/[id]», при этом идентификатор этого героя отображается вместо «[id]» — «/heroes/». 7', например.

(Я знаю, как добавить дочерний компонент непосредственно в родительский компонент без использования дочернего маршрута. Моя цель здесь — узнать, как работают дочерние маршруты. С прямым дочерним компонентом я знаю, как использовать ngOnChanges, но в этом случае это не так. меняется не свойство компонента @Input, а свойство маршрутизатора.)

Маршрутизация

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'heroes', component: HeroesComponent, runGuardsAndResolvers: 'always', children: [
    { path: ':id', component: HeroDetailComponent, runGuardsAndResolvers: 'always' }
  ] },
  { path: 'dashboard', component: DashboardComponent }
];

Выход дочернего маршрутизатора в родительском HeroesComponent

<section>
    <h2>All Heroes</h2>
    <div><a routerLink = "/detail">Create a hero</a></div>
    <table class = "table">
        <thead>
            <tr><th>Name</th><th>Location</th></tr>
        </thead>
        <tbody>
            <tr *ngFor = "let hero of heroes">
                <th><a routerLink = "/heroes/{{hero.id}}">{{hero.name}}</a></th>
                <td>{{hero.location}}</td>
                <td><a (click) = "delete(hero.id)">delete</a></td>
            </tr>
        </tbody>
    </table>
</section>

<router-outlet></router-outlet>

Код ключа в дочернем компоненте HeroDetailComponent

ngOnInit(): void {
  let id: string;
// I'll explain this comment later.
//    this.route.paramMap.subscribe((paramMap) => id = paramMap.get('id'));
  id = this.route.snapshot.paramMap.get('id');
  if (id) {
    this.mode = 'update';
    this.heroService.getHero(+id).subscribe((hero) => {
      this.hero = hero
    });
  } else {
    this.mode = 'add';
    this.hero = { id: 0, name: '', location: '', cuisine: 0 }
  }
}

Переход к /heroes дает мне следующее. (У меня уже был настроен API ресторана для руководства по .NET CORE, поэтому я использую его в качестве источника данных для этого руководства по Angular.)

Поле адреса браузера показывает «localhost:4200/heroes». Когда я навожу курсор на Masseria, в строке состояния браузера (это Chrome в Windows 10, если это имеет значение) отображается «http://localhost:4200/heroes/9». Перейдя по ссылке Masseria, я получаю:

Все идет нормально! Но затем, когда я нажимаю, скажем, на ссылку Takumi, хотя содержимое поля адреса браузера правильно изменяется на «http://localhost:4200/heroes/13», отображение не меняется: я все еще вижу детали для Masseria.

Теперь, если я щелкну адресное поле браузера и нажму Enter, вся страница обновится, показывая мне как список ресторанов, так и сведения о Такуми.

Я полагаю, что какое-то необходимое уведомление об обновлении не происходит. Я провел небольшое исследование. Что касается строки, которую я закомментировал в последнем фрагменте кода выше, я подумал, что, возможно, явная подписка на параметр маршрутизатора :id поможет, используя

this.route.paramMap.subscribe((paramMap) => id = paramMap.get('id'));

вместо того, чтобы брать параметр из моментального снимка маршрутизатора. Это не имело никакого эффекта.

Я также попытался добавить атрибут runGuardsAndResolvers: 'always' к родительскому и дочернему путям в моем массиве маршрутов (первый фрагмент кода выше), но это также не дало никакого эффекта.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
876
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Акк, понял. Я был на полпути с подпиской в ​​OnInit на paramMap роутера:

this.route.paramMap.subscribe((paramMap) => id = paramMap.get('id'));

Часть, которую я упустил, заключается в том, что все вычисления состояния должны быть внутри обратного вызова подписки, а не только установка значения идентификатора. Вот:

  ngOnInit(): void {
    let id: string;
    this.route.paramMap.subscribe((paramMap) => {
      id = paramMap.get('id');
      if (id) {
        this.mode = 'update';
        this.heroService.getHero(+id).subscribe((hero) => {
          this.hero = hero
        });
      } else {
        this.mode = 'add';
        this.hero = { id: 0, name: '', location: '', cuisine: 0 }
      }
    }
  );

Теперь работает как задумано.

Другие вопросы по теме