最近的一个项目中有面包屑导航这个功能,但是用bootstrap中的面包屑难以实现,参考
killerApp实现了想要的效果,在这分享一下。
1.配置路由
这里相当于父路由
export const visualizationRoutes = [
{
path: '',
component: VisualizationComponent,
children: [
{
path: 'dc-visual',
loadChildren: './dc-visual/dc-visual.module#DcVisualModule',
},
{
path: 'rack-monitor',
loadChildren: './rack-monitor/rack-monitor.module#RackMonitorModule',
data: {
breadcrumb: 'rack-monitor'
}
},
{
path: 'standard-rack-monitor',
loadChildren: './standard-rack-monitor/standard-rack-monitor.module#StandardRackMonitorModule',
data: {
breadcrumb: 'rack-monitor'
}
}
]
}
];
RackMonitorModule 对应的 rackMonitorRoutes
export const rackMonitorRoutes = [
{
path: '',
component: RackMonitorComponent,
children: [
{
path: 'summary',
component: RackSummaryComponent
}, {
path: 'psu',
component: RackPsuComponent
}, {
path: 'fans',
component: RackFansComponent
}, {
path: 'analysis',
component: RackAnalysisComponent
}
]
},
{
path: 'server-monitor',
loadChildren: './server-monitor/server-monitor.module#ServerMonitorModule',
data:{
breadcrumb: 'server-monitor'
}
}
];
其他的懒加载模块就按正常的路由配置就行
2.获取面包屑路由数据
/* VisualizationComponent */
import {Component, OnInit} from '@angular/core';
import {RouterActionService} from '../shared/services/public/router-action/router-action.service';
import {Router, ActivatedRoute, NavigationEnd, Params, PRIMARY_OUTLET} from "@angular/router";
import "rxjs/add/operator/filter";
interface IBreadcrumb {
label: string; // 用于显示的path
params?: Params; // 跳转时所带参数
url: string; // 跳转的url
}
@Component({
selector: 'app-visualization',
templateUrl: './visualization.component.html',
styleUrls: ['./visualization.component.scss']
})
export class VisualizationComponent implements OnInit {
public breadcrumbs: IBreadcrumb[];
public showActionBtn: boolean;
public showControlBtn: boolean;
constructor(private routerAction: RouterActionService,
private activatedRoute: ActivatedRoute,
private router: Router) {
this.breadcrumbs = [];
}
ngOnInit() {
const ROUTE_DATA_BREADCRUMB: string = "breadcrumb";
//subscribe to the NavigationEnd event
this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => {
//set breadcrumbs
let root: ActivatedRoute = this.activatedRoute.root;
this.breadcrumbs = this.getBreadcrumbs(root);
//remove duplicate element by label
//这个数组对象去重的方法很给力
this.breadcrumbs = this.breadcrumbs.reduce((x, y) => x.findIndex(e => e.label == y.label) < 0 ? [...x, y] : x, []);
console.log('%c breadcrumb list :', 'background: #222; color: white');
console.log(this.breadcrumbs);
});
}
private getBreadcrumbs(route: ActivatedRoute, url: string = "", breadcrumbs: IBreadcrumb[] = []): IBreadcrumb[] {
const ROUTE_DATA_BREADCRUMB: string = "breadcrumb";
//get the child routes
let children: ActivatedRoute[] = route.children;
//return if there are no more children
if (children.length === 0) {
return breadcrumbs;
}
//iterate over each children
for (let child of children) {
//verify primary route
if (child.outlet !== PRIMARY_OUTLET) {
continue;
}
//verify the custom data property "breadcrumb" is specified on the route
if (!child.snapshot.data.hasOwnProperty(ROUTE_DATA_BREADCRUMB)) {
return this.getBreadcrumbs(child, url, breadcrumbs);
}
//get the route's URL segment
let routeURL: string = child.snapshot.url.map(segment => segment.path).join("/");
//append route URL to URL
url += `/${routeURL}`;
/*console.log('%c url:', 'background: #222; color: red');
console.log(url);*/
//add breadcrumb
let breadcrumb: IBreadcrumb = {
label: child.snapshot.data[ROUTE_DATA_BREADCRUMB],
params: child.snapshot.params,
url: '/visualization' + url // 这个visualization是根据自己的跳转路由加的,不然点面包屑死活不跳呀
};
/*console.log('%c single breadcrumb:', 'background: #222; color: red');
console.log(breadcrumb);*/
breadcrumbs.push(breadcrumb);
//recursive
return this.getBreadcrumbs(child, url, breadcrumbs);
}
//we should never get here, but just in case
return breadcrumbs;
}
}
3.html中使用
总结
路由中的breadcrumb data位置不对可能会产生两个相同的面包屑,但是没关系最后数组里面去重就ok了,划重点:
this.breadcrumbs = this.breadcrumbs.reduce((x, y) => x.findIndex(e => e.label == y.label) < 0 ? [...x, y] : x, []);