角面包屑 [英] Angular Breadcrumb

查看:89
本文介绍了角面包屑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的个人项目(Angular 7)中实现面包屑.但是我无法按预期实现它.我发现了很多实现方法,但没有一个对我有用.

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

有人可以帮助我实现逻辑以按预期方式获得输出吗?我的路由模型如下:

  const路由:路由= [{小路: '',redirectTo:'dashboard',pathMatch:已满"},{小路: '',组件:HomeDashboardComponent,孩子们: [{路径:仪表板",组件:DashComponent,数据: {面包屑:仪表板"}},{路径:个人项目",组件:PresonalProjectsComponent,数据: {面包屑:个人项目"}}]},{路径:"personal-projects/:projectId",组件:ProjectDetailsComponent,数据: {面包屑:"},孩子们: [{小路: '',redirectTo:'backlog',pathMatch:已满"},{路径:"sprint",组件:SprintComponent,数据: {面包屑:冲刺"}},{路径:待办事项",组件:BacklogComponent,数据: {面包屑:积压"}}]}]; 

breadcrumb.component.ts文件为:

 公共面包屑:IBreadCrumb [];构造函数(专用路由器:路由器,专用ActivatedRoute:ActivatedRoute,){this.breadcrumbs = this.buildBreadCrumb(this.activatedRoute.root);}ngOnInit(){this.router.events.pipe(filter((event)=> Navigation实例的事件实例),uniqueUntilChanged(),).subscribe(()=> {this.breadcrumbs = this.buildBreadCrumb(this.activatedRoute.root);});}/***根据激活的路径递归构建面包屑.* @参数路线* @参数网址* @参数面包屑*/buildBreadCrumb(route:ActivatedRoute,url:string ='',面包屑:IBreadCrumb [] = []):IBreadCrumb [] {//如果没有可用的routeConfig,我们就在根路径上让标签= route.routeConfig&&route.routeConfig.data?route.routeConfig.data.breadcrumb:'';let isClickable = route.routeConfig&&route.routeConfig.data&&route.routeConfig.data.isClickable;让path = route.routeConfig&&route.routeConfig.data?route.routeConfig.path:'';//如果路由是动态路由,例如':id',请将其删除const lastRoutePart = path.split('/').pop();const isDynamicRoute = lastRoutePart.startsWith(':');如果(isDynamicRoute&& !! route.snapshot){const paramName = lastRoutePart.split(':')[1];路径= path.replace(lastRoutePart,route.snapshot.params [paramName]);标签= route.snapshot.params [paramName];}//在routeConfig中,完整路径不可用,//所以我们每次都重建它const nextUrl =路径?`$ {url}/$ {path}`:URL;const面包屑:IBreadCrumb = {标签:标签,网址:nextUrl,};//仅添加带有非空标签的路由const newBreadcrumbs =面包屑.label?[...面包屑,面包屑]:[...面包屑];如果(route.firstChild){//如果我们还不在当前路径上,//将有更多的孩子来照顾,以建立我们的面包返回this.buildBreadCrumb(route.firstChild,nextUrl,newBreadcrumbs);}返回newBreadcrumbs;}} 

解决方案

在这里发布我可能为时已晚,但是为了他人的利益,这是我的面包屑实现!我已经推荐了angular-breadcrumb npm软件包,并且是我自己量身定制的! https://www.npmjs.com/package/angular-breadcrumb ..>

breadcrumb.component.ts

 从'@ angular/core'导入{组件}从"../../models/breadcrumb.model"导入{面包屑}从"../../services/breadcrumb.service"导入{BreadcrumbService}@零件({选择器:面包屑",模板:< nav>< ol>< li * ngFor =让面包屑成为面包屑" class ="breadcrumb-item">< a [routerLink] ="[breadcrumb.url]"> {{Breadcrumb.displayName}}</a></li></ol></nav>`})出口类BreadcrumbComponent {面包屑:面包屑[]构造函数(私有BreadcrumbService:BreadcrumbService){this.breadcrumbService.breadcrumbChanged.subscribe((crumbs:Breadcrumb [])=> {this.onBreadcrumbChange(crumbs)})}私人onBreadcrumbChange(crumbs:Breadcrumb []){this.breadcrumbs =面包屑}} 

breadcrumb.model.ts

 从"@ angular/router"导入{Route}出口类面包屑{displayName:字符串网址:字符串路线:路线|无效的} 

breadcrumb.service.ts

 从'@ angular/core'导入{Injectable,EventEmitter}从'@ angular/router'导入{Router,ActivatedRouteSnapshot,Event,NavigationEnd}从'../models/breadcrumb.model'导入{面包屑}@Injectable()出口类BreadcrumbService {BreadcrumbChanged = new EventEmitter< Breadcrumb []>(false)私人面包屑:面包屑[] = []构造函数(专用路由器:路由器){this.router.events.subscribe((routeevent)=> {this.onRouteEvent(routeEvent)})}onRouteEvent(routeEvent:Event){如果(!(routeEnd实例的NavigationEnd)){返回}//获取父路由快照让路由= this.router.routerState.root.snapshot让url =''const newCrumbs = []而(route.firstChild!= null){路线= route.firstChild如果(route.routeConfig === null){继续}如果(!route.routeConfig.path){继续}url + =`/$ {this.createUrl(route)}`//检查直到路由包含其中定义的标题如果(!route.data ['breadcrumb']){继续}const newCrumb = this.createBreadcrumb(route,url)newCrumbs.push(newCrumb)}//用新的面包屑列表重新分配面包屑列表this.breadcrumbs = newCrumbsthis.breadcrumbChanged.emit(this.breadcrumbs)}createBreadcrumb(路线:ActivatedRouteSnapshot,网址:字符串):面包屑{返回 {displayName:route.data ['breadcrumb'],网址:url,路线:route.routeConfig}}createUrl(route:any){回程路线route.url.map(function(s){return s.toString())).join('/')}} 

I am trying to implement breadcrumb in my personal project(Angular 7). But I am unable to implement it as expected. I have found lot of implementation but none of them worked for me.

My requirement when i enter the URL : http://localhost:4200/personal-projects/2/backlog is
Personal Project > 2 > Backlog
But i am getting output as:
2 > Backlog

Can anyone help me to implement logic to get the output as expected? My routing model is as follows:

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 file as:

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;
  }
}

解决方案

May be I am too late to post here, but for the benefit of others, here's my breadcrumb implementation! I have referred angular-breadcrumb npm package and tailored on my own! 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('/')
  }
}

这篇关于角面包屑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆