Angular настройка заголовка в зависимости от активированного маршрута и его родителей - PullRequest
0 голосов
/ 08 апреля 2020

Моя цель: я хотел бы глобально прослушивать события маршрутизатора NavigationEnd и изменять заголовок веб-страницы в зависимости от пользовательских данных маршрута.

Текущий код (в app.component.ts):

this.router.events.pipe(
  filter((ev) => ev instanceof NavigationEnd),
  map(() => this.activatedRoute),
  map((route) => {
    while (route.firstChild) route = route.firstChild;
    return route;
  }),
  filter((route) => route.outlet === 'primary'),
  mergeMap((route) => route.data),
).subscribe((event) => this.title.setTitle(event['title']));

взято из этого урока

Приведенный выше код работает, но совсем не элегантно, посмотрите на необходимую конфигурацию маршрутизации:

app- routing.module.ts

const routes: Routes = [
  {
    path: 'user',
    loadChildren: () => import(`./user/user.module`).then(m => m.UserModule),
    data: { title: "Pagina Utente" }
  },
  {
    path: 'admin', loadChildren: () => import(`./admin/admin.module`).then(m => m.AdminModule),
    data: { title: "Pannello Admin" }
  },

  { path: '**', component: HomeComponent },
];

admin-routing.module.ts:

const routes: Routes = [
  {
    path: '', component: AdminPanelComponent,
    children: [
      {
        path: 'users', component: UsersComponent,
        data: { title: 'Pannello Admin: Utenti' }
      },
      {
        path: 'comuni', component: ComuniComponent,
        data: { title: 'Pannello Admin: Comuni' }
      },

    ]
  }
];

Как вы можете видеть, я уже указал, что для маршрута / admin должен быть "Pannello Admin" как заголовок, но мне нужно писать его снова и снова для каждого из его дочерних маршрутов.

Я попытался исправить эту проблему, изменив код app.component.ts следующим образом:

this.router.events.pipe(
  filter((ev) => ev instanceof NavigationEnd),
  map(() => this.activatedRoute),
  map((route) => {
    let title = route.data['title'] || '';
    while (route.firstChild) {
      route = route.firstChild;
      title+= route.data['title'];
    }
    return route;
  }),
  filter((route) => route.outlet === 'primary'),
  mergeMap((route) => route.data),
).subscribe((event) => this.title.setTitle(event['title']));

Я ожидал, что этот код будет работать, и установил в качестве заголовка конкатенацию свойства data ['title'] соответствующих маршрутов. Однако это не работает и просто выдает пустые заголовки (данные ['title'] всегда по какой-то причине не определены)

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

Я решил проблему, используя этот код в конструкторе app.component.ts:

this.router.events.pipe(
  filter((ev) => ev instanceof NavigationEnd),
  map(() => this.activatedRoute),
).subscribe((activatedRoute: ActivatedRoute) => this.title.setTitle(activatedRoute.snapshot.data['title'] || 'Gestionale Incarichi'));
0 голосов
/ 08 апреля 2020
export class AppRouterModule {
   constructor(private router: Router, private eventService: EventService) {
      this.router.events.subscribe(event => {
         if (event instanceof NavigationStart) {
            this.eventService.StartNavigationSpinner();
         }
      });
   }
}

Я помещаю подписки на события навигации в сам AppRouterModule, затем, когда происходит определенное событие, я отправляю его в службу EventService, которую все загруженные компоненты прослушивают, чтобы вывести этот список:

  this.EventService.NavigationStartEvent.subscribe(() => {
         if (this.showGlobalSpinner) return;
         this.showGlobalSpinner = true;
      });

Служба событий является Служба, которая выглядит следующим образом:

export class EventService {
   NavigationEndEvent = new EventEmitter();
   NavigationStartEvent = new EventEmitter();
...

Весь анализ выполняется в модуле app.router, просто отправит событие в загруженную подписку с измененным названием? Это может быть любой загруженный компонент.

Если перезапись происходит слишком часто, это происходит потому, что страницы перезагружаются с помощью цикла angular маршрутизации / рендеринга. Подозрительным является конфигурация loadChildren в маршрутах.

Я думаю, что вы хотите, чтобы главная страница загружалась один раз и меняла заголовок только в случае изменения одной дочерней страницы. Я считаю, что это означает, что вам нужен еще один ngRouterOutput. Документация Angular вызывает головокружение от этой концепции. Идея, что дети могут существовать на любой странице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...