File
Implements
Metadata
selector |
cd-breadcrumbs |
styleUrls |
./breadcrumbs.component.scss |
templateUrl |
./breadcrumbs.component.html |
Methods
isPromise
|
isPromise(value: any)
|
|
Parameters :
Name |
Type |
Optional |
value |
any
|
No
|
|
ngOnDestroy
|
ngOnDestroy()
|
|
|
wrapIntoObservable
|
wrapIntoObservable(value: T | Promise | Observable)
|
|
Type parameters :
|
Parameters :
Name |
Type |
Optional |
value |
T | Promise<T> | Observable<T>
|
No
|
Returns : Observable<T>
|
Private
defaultResolver
|
Default value : new BreadcrumbsResolver()
|
|
finished
|
Default value : false
|
|
Usefull for e2e tests.
This allow us to mark the breadcrumb as pending during the navigation from
one page to another.
This resolves the problem of validating the breadcrumb of a new page and
still get the value from the previous
|
subscription
|
Type : Subscription
|
|
import { Component, Injector, OnDestroy } from '@angular/core';
import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router';
import { from, Observable, of, Subscription } from 'rxjs';
import { concat, distinct, filter, first, flatMap, toArray } from 'rxjs/operators';
import { BreadcrumbsResolver, IBreadcrumb } from '../../../shared/models/breadcrumbs';
@Component({
selector: 'cd-breadcrumbs',
templateUrl: './breadcrumbs.component.html',
styleUrls: ['./breadcrumbs.component.scss']
})
export class BreadcrumbsComponent implements OnDestroy {
crumbs: IBreadcrumb[] = [];
/**
* Usefull for e2e tests.
* This allow us to mark the breadcrumb as pending during the navigation from
* one page to another.
* This resolves the problem of validating the breadcrumb of a new page and
* still get the value from the previous
*/
finished = false;
subscription: Subscription;
private defaultResolver = new BreadcrumbsResolver();
constructor(private router: Router, private injector: Injector) {
this.subscription = this.router.events
.pipe(filter((x) => x instanceof NavigationStart))
.subscribe(() => {
this.finished = false;
});
this.subscription = this.router.events
.pipe(filter((x) => x instanceof NavigationEnd))
.subscribe(() => {
const currentRoot = router.routerState.snapshot.root;
this._resolveCrumbs(currentRoot)
.pipe(
flatMap((x) => x),
distinct((x) => x.text),
toArray(),
flatMap((x) => {
const y = this.postProcess(x);
return this.wrapIntoObservable<IBreadcrumb[]>(y).pipe(first());
})
)
.subscribe((x) => {
this.finished = true;
this.crumbs = x;
});
});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
private _resolveCrumbs(route: ActivatedRouteSnapshot): Observable<IBreadcrumb[]> {
let crumbs$: Observable<IBreadcrumb[]>;
const data = route.routeConfig && route.routeConfig.data;
if (data && data.breadcrumbs) {
let resolver: BreadcrumbsResolver;
if (data.breadcrumbs.prototype instanceof BreadcrumbsResolver) {
resolver = this.injector.get(data.breadcrumbs);
} else {
resolver = this.defaultResolver;
}
const result = resolver.resolve(route);
crumbs$ = this.wrapIntoObservable<IBreadcrumb[]>(result).pipe(first());
} else {
crumbs$ = of([]);
}
if (route.firstChild) {
crumbs$ = crumbs$.pipe(concat(this._resolveCrumbs(route.firstChild)));
}
return crumbs$;
}
postProcess(breadcrumbs: IBreadcrumb[]) {
const result = [];
breadcrumbs.forEach((element) => {
const split = element.text.split('/');
if (split.length > 1) {
element.text = split[split.length - 1];
for (let i = 0; i < split.length - 1; i++) {
result.push({ text: split[i], path: null });
}
}
result.push(element);
});
return result;
}
isPromise(value: any): boolean {
return value && typeof value.then === 'function';
}
wrapIntoObservable<T>(value: T | Promise<T> | Observable<T>): Observable<T> {
if (value instanceof Observable) {
return value;
}
if (this.isPromise(value)) {
return from(Promise.resolve(value));
}
return of(value as T);
}
}
<ol *ngIf="crumbs.length"
class="breadcrumb">
<li *ngFor="let crumb of crumbs; let last = last"
[ngClass]="{ 'active': last && finished }"
class="breadcrumb-item">
<a *ngIf="!last && crumb.path !== null"
[routerLink]="crumb.path">{{ crumb.text }}</a>
<span *ngIf="last || crumb.path === null">{{ crumb.text }}</span>
</li>
</ol>
@import '../../../../defaults';
.breadcrumb {
padding: 8px 0;
background-color: transparent;
border-radius: 0;
}
.breadcrumb > li + li:before {
padding: 0 5px 0 7px;
color: $color-breadcrumb;
font-family: 'ForkAwesome';
content: '\f101';
}
.breadcrumb > li > span {
color: $color-breadcrumb;
}
Legend
Html element with directive