具有动态标签的角面包屑

时间:2019-07-10 18:24:59

标签: angular angular-router

我想使用面包屑动态创建面包屑导航。像这样:

  

主页> A类>子类别1> XYZ

其中“类别A”和“子类别1”是静态的,而“ XYZ”是动态的。该动态标签仅在初始化各个组件之后才存在,因为内容是从远程服务器加载的。层次结构来自路由器配置,其中路由具有子级。

我试图通过ActivatedRoute访问当前组件,但是我只能找到组件名称,这在这方面无济于事。我的下一个想法是监视RouterOutlet的更改,但是似乎没有事件引起更改。

我模糊的想法是让组件实现这样的接口:

interface Named {
  readonly name: Observable<string>
}

...并以某种方式订阅了此Observable,但为此,我需要组件实例!

如何从RouterOutlet当前显示的组件中获取计算字符串?

2 个答案:

答案 0 :(得分:2)

我的建议是使用 ngOnInit,而不是使用组件的 Route Resolver 钩子从服务中调用将带来必要数据的方法。

Angular Route Resolvers 用于在用户从一个路由重定向到另一个路由时预取一些数据。新可用的页面(组件)已经拥有页面中需要呈现的数据。

基本上,解析器是一种实现 Resolve 接口的服务:https://angular.io/api/router/Resolve

来自文档:

<块引用>

该接口定义了一个 resolve() 方法,该方法在 导航开始。路由器等待数据解析之前 路由终于激活了

在以下示例中,我从您的层次结构示例中删除了一个级别,并假设子类别是动态的。

解析器的代码将是:

import { Injectable } from '@angular/core';
import { Resolve, RouterStateSnapshot,ActivatedRouteSnapshot} from "@angular/router";
import { HttpClient } from "@angular/common/http";
import { Observable, of } from "rxjs";

@Injectable({
  providedIn: 'root'
})

export class DynamicSubcategoryResolver implements Resolve<any> {
  
  constructor(private _http: HttpClient) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any> {

    const subcategoryId: string | null = route.paramMap.get("subcategoryId");
    // other route params are in route.paramMap


    // return this._http.get("url");
    return of({
      breadcrumb: "(Dynamic breadcrumb) Subcategory " + subcategoryId,
      foo: "bar",
      bar: "baz"
    });
  }
} 

现在,路由定义如下:

const routes: Routes = [
  {
    path: "",
    component: HomeComponent,
    data: {
      breadcrumb: "Home"
    },
    children: [
      {
        path: "category-a",
        component: CategoryAComponent,
        data: {
          breadcrumb: "CategoryA" // static breadcrumb
        },
        children: [
          {
            path: "subcategory/:subcategoryId",
            component: DynamicSubcategoryComponent,
            resolve: {
              apiData: DynamicSubcategoryResolver
            }
          }
        ]
      }
    ]
  }
];

来自解析器的数据将在:ActivatedRoute.snapshot.data 对象中可用:

export class DynamicSubcategoryComponent implements OnInit {

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    const data = this.activatedRoute.snapshot.data;
    console.log("apiData: ", data.apiData);
  }
}

最后,在面包屑生成器中,代码应如下所示:

const routeData: Data = route.snapshot.data;

if (routeData.breadcrumb) {
   breadcrumbs.push({
     label: routeData.breadcrumb, 
     url: url 
   });
} else if (routeData.apiData && routeData.apiData.breadcrumb) {
  breadcrumbs.push({
    label: routeData.apiData.breadcrumb,
    url: url
  });
}

完整的代码: https://stackblitz.com/edit/angular-ivy-vuroqk

答案 1 :(得分:0)

尝试使用路由器和路由:

import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';

和:

constructor(private router: Router, private route: ActivatedRoute) {}

然后:

router.events.forEach(event => {
  if (event instanceof NavigationEnd) {
    // access all route data here
    this.route = route;
  }
});