提问人:David Jackson 提问时间:4/1/2022 最后编辑:David Jackson 更新时间:7/1/2022 访问量:605
如何在面包屑中显示层次结构
How to display hierarchy in breadcrumb
问:
我是使用 Angular 的新手,想包含一个动态的全局面包屑。我将组件层次结构称为 component1->component2->component3->component4。 第二个组件从第一个组件获取 id,第三个组件从第二个组件获取 id,依此类推。
breadcrumb.component.html
<ul>
<li *ngFor="let breadcrumb of (breadcrumbs$ | async)">
<a [href]="breadcrumb.url">{{ breadcrumb.label }}</a>
</li>
</ul>
面包屑.component.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { Breadcrumb } from 'src/models/Breadcrumb';
import { BreadcrumbService } from 'src/services/breadcrumb.service';
@Component({
selector: 'app-breadcrumb',
templateUrl: './breadcrumb.component.html',
styleUrls: ['./breadcrumb.component.css']
})
export class BreadcrumbComponent {
breadcrumbs$: Observable<Breadcrumb[]>;
constructor(private readonly breadcrumbService: BreadcrumbService) {
this.breadcrumbs$ = breadcrumbService.breadcrumbs$;
}
}
面包屑模型
export interface Breadcrumb {
label: string;
url: string;
}
面包屑服务
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Data, NavigationEnd, Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { Breadcrumb } from 'src/models/Breadcrumb';
@Injectable({
providedIn: 'root'
})
export class BreadcrumbService {
// Subject emitting the breadcrumb hierarchy
private readonly _breadcrumbs$ = new BehaviorSubject<Breadcrumb[]>([]);
// Observable exposing the breadcrumb hierarchy
readonly breadcrumbs$ = this._breadcrumbs$.asObservable();
constructor(private router: Router) {
this.router.events.pipe(
// Filter the NavigationEnd events as the breadcrumb is updated only when the route reaches its end
filter((event) => event instanceof NavigationEnd)
).subscribe(event => {
// Construct the breadcrumb hierarchy
const root = this.router.routerState.snapshot.root;
const breadcrumbs: Breadcrumb[] = [];
this.addBreadcrumb(root, [], breadcrumbs);
// Emit the new hierarchy
this._breadcrumbs$.next(breadcrumbs);
});
}
private addBreadcrumb(route: ActivatedRouteSnapshot, parentUrl: string[], breadcrumbs: Breadcrumb[]) {
if (route) {
// Construct the route URL
const routeUrl = parentUrl.concat(route.url.map(url => url.path));
// Add an element for the current route part
if (route.data.breadcrumb) {
const breadcrumb = {
label: this.getLabel(route.data),
url: '/' + routeUrl.join('/')
};
breadcrumbs.push(breadcrumb);
}
// Add another element for the next route part
//this.addBreadcrumb(route.firstChild, routeUrl, breadcrumbs);
}
}
private getLabel(data: Data) {
// The breadcrumb can be defined as a static string or as a function to construct the breadcrumb element out of the route data
return typeof data.breadcrumb === 'function' ? data.breadcrumb(data) : data.breadcrumb;
}
}
我不确定提及路线的正确方式是什么。我尝试了多种 StackOverflow 解决方案,但它不起作用。ids存在于各个组件中,但我需要在全局级别上访问它们才能在面包屑中访问它们。
答:
0赞
Dm Mh
7/1/2022
#1
您的路由结构完全由您决定,但为了让您的生活更轻松,您可以将 ID 作为路由器 URL 的一部分。例如 www.host.com/category/:cId/subcategory/:scId。 通过这种方法,您可以使用 angular 路由器访问 id。
constructor(private route: ActivatedRouteSnapshot) {}
...
this.route.paramMap.get('cId');
this.route.paramMap.get('scId');
OR
this.route.params.cId;
this.route.params.scId;
如果您无法从父路由中读取参数,请考虑将 paramsInheritanceStrategy 设置为 'always' (https://angular.io/api/router/ExtraOptions)。
评论