@seacjs

Как правильно реализовать хлебные крошки в условиях ленивой загрузки?

Всем привет! Как правильно реализовать хлебные крошки в условиях ленивой загрузки?
У меня есть блог со структурой - /blog/rubricSlug/blogPageSlug, В зависимости от открытой страницы подгружается соответствующий ей модуль(который естественно подтягивает компоненты и прочее).
BlogModule:
import { BlogItemModule } from './blog-item/blog-item.module';
import { SharedModule } from './../../shared/shared.module';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { BlogComponent } from './blog.component';
const routes: Routes = [
  {
    path: '',
    component: BlogComponent,
    data: {breadcrumb: 'Блог'}
  },
  {
    path: ':slug',
    loadChildren: () => import('./rubric/rubric.module').then((m) => m.RubricModule),
  }
];
@NgModule({
  declarations: [
    BlogComponent
  ],
  imports: [
    BlogItemModule,
    SharedModule,
    RouterModule.forChild(routes)
  ],
})
export class BlogModule { }

RubricModule:
import { RubricComponent } from './rubric.component';
import { SharedModule } from './../../../shared/shared.module';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { BlogItemModule } from '../blog-item/blog-item.module';
const routes: Routes = [
  {
    path: '',
    component: RubricComponent,
    data: {breadcrumb: 'Рубрика'}
  },
  {
    path: ':slug',
    loadChildren: () => import('./blog-page/blog-page.module').then((m) => m.BlogPageModule),
  }
];
@NgModule({
  declarations: [
    RubricComponent
  ],
  imports: [
    BlogItemModule,
    SharedModule,
    RouterModule.forChild(routes)
  ]
})
export class RubricModule { }

BlogPageModule:
import { SharedModule } from './../../../../shared/shared.module';
import { BlogPageComponent } from './blog-page.component';
import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
const routes: Routes = [
  {
    path: '',
    component: BlogPageComponent,
    data: {breadcrumb: 'Страница'}
  }
];
@NgModule({
  declarations: [
    BlogPageComponent
  ],
  imports: [
    SharedModule,
    RouterModule.forChild(routes)
  ]
})
export class BlogPageModule { }

Для хлебных крошек у меня создан BreadcrumbsComponent который подключается в app.component
BreadcrumbsComponent:
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { filter, map } from 'rxjs/operators';
@Component({
  selector: 'app-breadcrumbs',
  templateUrl: './breadcrumbs.component.html',
  styleUrls: ['./breadcrumbs.component.less']
})
export class BreadcrumbsComponent implements OnInit {
  public breadcrumbs = [];
  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute
  ) { }
  ngOnInit() {
    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .pipe(map(() => this.activatedRoute))
      .pipe(map((route) => {
        while (route.firstChild) { route = route.firstChild; }
        return route;
      }))
    .subscribe(route => {
        let snapshot = this.router.routerState.snapshot;
        this.breadcrumbs = [];
        let url = snapshot.url;
        let routeData = route.snapshot.data;
        let label = routeData['breadcrumb'];
        let params = snapshot.root.params;
        this.breadcrumbs.push({
          url: url,
          label: label,
          params: params
        });
    });
  }
}

В таком случае на странице блога или рубрики получаем только один конечный роут.
Подскажите как можно получить и родительские данные? И как передать slug динамически из этих компонентов в breacrumbsComponent?
  • Вопрос задан
  • 685 просмотров
Пригласить эксперта
Ответы на вопрос 2
Xuxicheta
@Xuxicheta Куратор тега Angular
инженер
Поскольку крошки многоуровневые есть такое предложение.
1. Должен быть сервис, принимающий данные по крошкам. С методами создать крошку указанного уровня и удалить крошку.
2. Должен быть способ улавливать события роутера на нескольких уровнях, чтобы отправлять data в вышеуказанные сервис.
Это можно делать глобально слушая роутер, как у вас и проходя по firstChild собирать data, но я бы предложил сделать директиву на RouterOutlet которая будет принимать уровень, реагировать на события activate и deactivate и выставлять крошки по содержимому activatedRouteData
Ответ написан
Комментировать
@seacjs Автор вопроса
В итоге сделал сервис который хранит информацию о крошках. Но запись сделал для каждого модуля полностью, потому что в промежуточных роутах информация динамическая(ее нельзя записать в data). Собственно это было очевидно с самого начала, но что то не подумал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы