在 Angular 18 中使用路由历史记录实现面包屑系统

问题描述 投票:0回答:1

我目前正在使用路由历史记录实现面包屑系统。当当前路径是根路径时就会出现问题。例如,我设置了加载用户表视图的根路径。单击用户时,它将导航到用户添加/编辑页面。在用户添加/编辑页面上,面包屑应显示为“用户 > 用户添加/编辑”,但它只显示“用户添加/编辑”。

我不能简单地检查当前 URL 是否包含根作为子集并附加“用户”,因为每个路径都包含根作为子集。我应该如何处理这种情况并正确实施面包屑?

import { Injectable } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
import { BehaviorSubject } from 'rxjs';

interface RouteHistory {
  url: string;
  breadcrumb: string | null;
}

@Injectable({
  providedIn: 'root'
})
export class RoutingHistoryService {
  private history: RouteHistory[] = [];
  private historySubject = new BehaviorSubject<RouteHistory[]>(this.history);

  constructor(private router: Router, private route: ActivatedRoute) {
    this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ).subscribe(() => {
      this.addBreadcrumbHistory();
    });
  }

  private addBreadcrumbHistory() {
    let url = '';
    let currentRoute = this.route.root;
    let breadcrumbLabel: string | null = null;

    while (currentRoute.children.length > 0) {
      const childRoutes = currentRoute.children;
      currentRoute = childRoutes[0];
      const routeURL: string = currentRoute.snapshot.url.map(segment => segment.path).join('/');
      url = `${url}/${routeURL}`.replace(/\/$/, '');

      if (currentRoute.snapshot.data['breadcrumb']) {
        breadcrumbLabel = currentRoute.snapshot.data['breadcrumb'];
      }
    }

    if (!url || url === '/') {
      this.history.push({
        url: '/',
        breadcrumb: 'Users'   // In order to set the breadcrumb for the root 
      });
    }else{
      this.history.push({
        url,
        breadcrumb: breadcrumbLabel
      });
    }

    this.historySubject.next(this.history);
  }

  getHistory() {
    return this.historySubject.asObservable();
  }

  getBreadcrumbForUrl(url: string): string | null {
    const historyEntry = this.history.find(entry => entry.url === url);
    return historyEntry ? historyEntry.breadcrumb : null;
  }

  clearHistory() {
    this.history = [];
    this.historySubject.next(this.history);
  }
}

这里还有面包屑组件.ts

import {Component, OnDestroy, OnInit} from '@angular/core';
import {Subscription} from 'rxjs';
import {RoutingHistoryService} from "../../../service/routing.history.service";

@Component({
  selector: 'app-breadcrumb',
  templateUrl: './breadcrumb.component.html',
  styleUrl: './breadcrumb.component.scss'
})

export class BreadcrumbComponent implements OnInit, OnDestroy {
  history: Array<{ url: string, breadcrumb: string | null }> = [];
  breadcrumbTrail: any[] = [];
  private historySubscription: Subscription;

  constructor(private routingHistoryService: RoutingHistoryService) {
  }

  ngOnInit() {
    this.historySubscription = this.routingHistoryService.getHistory().subscribe(updatedHistory => {
      this.history = updatedHistory;
      this.updateBreadcrumbTrail();
    });
  }

  private updateBreadcrumbTrail() {
    const currentUrl = this.history.length > 0 ? this.history[this.history.length - 1].url : '';
    const urlSegments = currentUrl.split('/').filter(segment => segment);

    this.breadcrumbTrail = [];
    let urlAccumulator = '';

    if(currentUrl === '' || currentUrl === '/'){
      this.breadcrumbTrail.push({
        label: 'Users',
        routerLink: '/'
      });
    }

    urlSegments.forEach((segment, index) => {
      urlAccumulator = `${urlAccumulator}/${segment}`;
      const breadcrumbLabel = this.routingHistoryService.getBreadcrumbForUrl(urlAccumulator);
      this.breadcrumbTrail.push({
        label: breadcrumbLabel,
        routerLink: index < urlSegments.length - 1 ? urlAccumulator : null 
      });
    });
  }

  ngOnDestroy() {
    if (this.historySubscription) {
      this.historySubscription.unsubscribe();
    }
  }
}

我该如何解决这个问题?

我也为根路径设置了面包屑标签,但它没有被应用。

angular primeng breadcrumbs
1个回答
0
投票

确保根始终包含在面包屑路径中。

private updateBreadcrumbTrail() {
  const currentUrl = this.history.length > 0 ? this.history[this.history.length - 1].url : '';
  const urlSegments = currentUrl.split('/').filter(segment => segment);

  this.breadcrumbTrail = [];
  let urlAccumulator = '';

  // Always add the root breadcrumb 'Users' manually if it's not already in the trail.
  if (this.history.find(entry => entry.url === '/')) {
    this.breadcrumbTrail.push({
      label: 'Users',
      routerLink: '/'
    });
  }

  // Iterate through the remaining segments and build the breadcrumb trail.
  urlSegments.forEach((segment, index) => {
    urlAccumulator = `${urlAccumulator}/${segment}`;
    const breadcrumbLabel = this.routingHistoryService.getBreadcrumbForUrl(urlAccumulator);
    
    if (breadcrumbLabel) {
      this.breadcrumbTrail.push({
        label: breadcrumbLabel,
        routerLink: index < urlSegments.length - 1 ? urlAccumulator : null
      });
    }
  });
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.