import { Injectable, NgZone } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { BaseService } from '../../core/common/base/base.service'; import { BreadcrumbItem } from '../../shared/components/breadcrumb/definition/breadcrumb-item'; import { IBreadCrumbComponent } from '../../shared/components/breadcrumb/definition/IBreadCrumbComponent'; @Injectable() export class BreadCrumbResolverService extends BaseService { private activeComponents = []; private parentComponents = []; private breadCrumbs: Observable = Observable.of([]); constructor( private router: Router, private zone: NgZone ) { super(); } public push(component: any) { const existingComponentIndex = this.activeComponents.map(x => x.constructor.name).indexOf(component.constructor.name); if (existingComponentIndex !== -1) { this.activeComponents.splice(existingComponentIndex, 1); } this.activeComponents.push(component); } public clear() { this.activeComponents.length = 0; this.breadCrumbs = Observable.of([]); } public resolve(activatedRoute: ActivatedRoute): Observable { this.breadCrumbs = null; const routeComponents = this.getComponentsFromRoute(activatedRoute, []); this.activeComponents.filter(x => routeComponents.indexOf(x.constructor.name) !== -1).forEach(x => { if (x.hasOwnProperty('breadCrumbs')) { const componentItems = this.resolveDependentComponents((x).breadCrumbs, []); this.breadCrumbs = Observable.of(componentItems); } }); return this.breadCrumbs; } private getComponentsFromRoute(activatedRoute: ActivatedRoute, routeComponents: any[]): any[] { activatedRoute.children.forEach(x => { if (x.children.length > 0) { this.getComponentsFromRoute(x.children[0], routeComponents); } if (x.component) { routeComponents.push(x.component['name']); } }); if (activatedRoute.component) { routeComponents.push(activatedRoute.component['name']); } return routeComponents; } resolveDependentComponents(items: Observable, components: any[]): any[] { items .pipe(takeUntil(this._destroyed)) .subscribe(breadCrumbs => { breadCrumbs.forEach(async item => { const parentComponent = item.parentComponentName ? this.findComponent(item.parentComponentName) : null; if (parentComponent && parentComponent.hasOwnProperty('breadCrumbs')) { components = this.pushToStart(components, this.resolveDependentComponents((parentComponent).breadCrumbs, components)); } else if (item.notFoundResolver) { components = this.pushToStart(components, item.notFoundResolver); //components = this.pushToStart(components, [unresolvedComponentItems]) } }); components = this.pushToEnd(components, breadCrumbs); }); return components; } private findComponent(componentName: string): any { for (let i = 0; i < this.activeComponents.length; i++) { if (this.activeComponents[i].constructor.name === componentName) { return this.activeComponents[i]; } } return null; } pushToStart(first: any[], second: any[]) { return [].concat(second.filter(x => first.map(firstX => firstX.label).indexOf(x.label) === -1), first); } pushToEnd(first: any[], second: any[]) { return [].concat(first, second.filter(x => first.map(firstX => firstX.label).indexOf(x.label) === -1)); } }