【问题标题】:Angular Breadcrumb角面包屑
【发布时间】:2019-09-18 05:28:55
【问题描述】:

我正在尝试在我的个人项目(Angular 7)中实现面包屑。但我无法按预期实施。我找到了很多实现,但没有一个对我有用。

我输入 URL 时的要求:http://localhost:4200/personal-projects/2/backlog
个人项目 > 2 > 待办事项
但我得到的输出是:
2 > Backlog

谁能帮我实现逻辑以获得预期的输出? 我的路由模型如下:

const routes: Routes = [
    {
        path: '',
        redirectTo: 'dashboard',
        pathMatch: 'full'
    },
    {
        path: '',
        component: HomeDashboardComponent,
        children: [
            {
                path: 'dashboard',
                component: DashComponent,
                data: {
                    breadcrumb: 'Dashboard'
                }
            },
            {
                path: 'personal-projects',
                component: PresonalProjectsComponent,
                data: {
                    breadcrumb: 'Personal Project'
                }
            }
        ]
    },
    {
        path: 'personal-projects/:projectId',
        component: ProjectDetailsComponent,
        data: {
            breadcrumb: ''
        },
        children: [
            {
                path: '',
                redirectTo: 'backlog',
                pathMatch: 'full'
            },
            {
                path: 'sprint',
                component: SprintComponent,
                data: {
                    breadcrumb: 'Sprint'
                }
            },
            {
                path: 'backlog',
                component: BacklogComponent,
                data: {
                    breadcrumb: 'backlog'
                }
            }
        ]
    }
];

breadcrumb.component.ts 文件为:

public breadcrumbs: IBreadCrumb[];

  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
  ) {
    this.breadcrumbs = this.buildBreadCrumb(this.activatedRoute.root);
  }

  ngOnInit() {
    this.router.events.pipe(
      filter((event) => event instanceof NavigationEnd),
      distinctUntilChanged(),
    ).subscribe(() => {
      this.breadcrumbs = this.buildBreadCrumb(this.activatedRoute.root);
    });
  }

  /**
   * Recursively build breadcrumb according to activated route.
   * @param route
   * @param url
   * @param breadcrumbs
   */
  buildBreadCrumb(route: ActivatedRoute, url: string = '', breadcrumbs: IBreadCrumb[] = []): IBreadCrumb[] {
    // If no routeConfig is avalailable we are on the root path
    let label = route.routeConfig && route.routeConfig.data ? route.routeConfig.data.breadcrumb : '';
    let isClickable = route.routeConfig && route.routeConfig.data && route.routeConfig.data.isClickable;
    let path = route.routeConfig && route.routeConfig.data ? route.routeConfig.path : '';

    // If the route is dynamic route such as ':id', remove it
    const lastRoutePart = path.split('/').pop();
    const isDynamicRoute = lastRoutePart.startsWith(':');
    if (isDynamicRoute && !!route.snapshot) {
      const paramName = lastRoutePart.split(':')[1];
      path = path.replace(lastRoutePart, route.snapshot.params[paramName]);
      label = route.snapshot.params[paramName];
    }

    // In the routeConfig the complete path is not available,
    // so we rebuild it each time
    const nextUrl = path ? `${url}/${path}` : url;

    const breadcrumb: IBreadCrumb = {
      label: label,
      url: nextUrl,
    };

    // Only adding route with non-empty label
    const newBreadcrumbs = breadcrumb.label ? [...breadcrumbs, breadcrumb] : [...breadcrumbs];
    if (route.firstChild) {
      // If we are not on our current path yet,
      // there will be more children to look after, to build our breadcumb
      return this.buildBreadCrumb(route.firstChild, nextUrl, newBreadcrumbs);
    }
    return newBreadcrumbs;
  }
}

【问题讨论】:

    标签: angular breadcrumbs


    【解决方案1】:

    可能我在这里发帖太晚了,但为了其他人的利益,这是我的面包屑实现!我已经参考了 angular-breadcrumb npm 包并自行定制! https://www.npmjs.com/package/angular-breadcrumb.

    breadcrumb.component.ts

    import { Component } from '@angular/core'
    import { Breadcrumb } from '../../models/breadcrumb.model'
    import { BreadcrumbService } from '../../services/breadcrumb.service'
    
    @Component({
      selector: 'breadcrumb',
      template: `
          <nav>
            <ol>              
              <li *ngFor="let breadcrumb of breadcrumbs" class="breadcrumb-item">
                <a [routerLink]="[breadcrumb.url]">{{ breadcrumb.displayName }}</a>
              </li>
            </ol>
          </nav>
      `
    })
    export class BreadcrumbComponent {
      breadcrumbs: Breadcrumb[]
      constructor(private breadcrumbService: BreadcrumbService) {
        this.breadcrumbService.breadcrumbChanged.subscribe((crumbs: Breadcrumb[]) => {
          this.onBreadcrumbChange(crumbs)
        })
      }
    
      private onBreadcrumbChange(crumbs: Breadcrumb[]) {
        this.breadcrumbs = crumbs
      }
    }
    

    breadcrumb.model.ts

    import { Route } from '@angular/router'
    
    export class Breadcrumb {
        displayName: string
        url: string
        route: Route | null
    }
    

    breadcrumb.service.ts

    import { Injectable, EventEmitter } from '@angular/core'
    import { Router, ActivatedRouteSnapshot, Event, NavigationEnd } from '@angular/router'
    import { Breadcrumb } from '../models/breadcrumb.model'
    
    @Injectable()
    export class BreadcrumbService {
      breadcrumbChanged = new EventEmitter<Breadcrumb[]>(false)
    
      private breadcrumbs: Breadcrumb[] = []
    
      constructor(private router: Router) {
        this.router.events.subscribe((routeEvent) => { this.onRouteEvent(routeEvent) })
      }
    
      onRouteEvent(routeEvent: Event) {
        if (!(routeEvent instanceof NavigationEnd)) { return }
    
        // Get the parent route snapshot
        let route = this.router.routerState.root.snapshot
        let url = ''
    
        const newCrumbs = []
    
        while (route.firstChild != null) {
          route = route.firstChild
    
          if (route.routeConfig === null) { continue }
          if (!route.routeConfig.path) { continue }
    
          url += `/${this.createUrl(route)}`
    
          // check until the routes contains title defined in it
          if (!route.data['breadcrumb']) { continue }
    
          const newCrumb = this.createBreadcrumb(route, url)
          newCrumbs.push(newCrumb)
        }
    
        // reassign breadcrumb list with new breadcrumb list
        this.breadcrumbs = newCrumbs
        this.breadcrumbChanged.emit(this.breadcrumbs)
      }
    
      createBreadcrumb(route: ActivatedRouteSnapshot, url: string): Breadcrumb {
        return {
          displayName: route.data['breadcrumb'],
          url: url,
          route: route.routeConfig
        }
      }
    
      createUrl(route: any) {
        return route && route.url.map(function (s) { return s.toString() }).join('/')
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多