【问题标题】:Angular2 router, get route data from url, to display breadcrumbsAngular2路由器,从url获取路由数据,显示面包屑
【发布时间】:2016-11-13 17:22:15
【问题描述】:

我正在使用angular2 router

要绘制 url 的面包屑,假设 site.com/a/b/c/15 我执行以下操作:

  1. 获取site.com/a/b/c/15的路由并获取与该路由关联的漂亮名称
  2. 获取site.com/a/b/c的路由并获取与该路由关联的漂亮名称
  3. 获取site.com/a/b的路由并获取与该路由关联的漂亮名称
  4. 获取site.com/a的路由并获取与该路由关联的漂亮名称

假设我确实有以下路线:

{ path: 'a', component: A, data:{prettyName: 'I am A'}}
{ path: 'b', component: B, data:{prettyName: 'I am B'}},
{ path: 'c', component: C, data:{prettyName: 'I am C'}},

我的过程的结果将是一个包含{"I am C", "I am B", "I am C"} 的数组,因此我可以显示一个很好的面包屑"I am A > I am B > I am C" 来解释当前的路线。

这用于与路由器不推荐使用的一起工作

this.router.recognize(url).then((instruction) => {
    instruction.component.routeData.get('prettyName') // Would return 'I am ..'

但是现在;使用最后一个路由器,我无法再处理此识别逻辑了。

如何获取与 url 关联的路由数据?

【问题讨论】:

    标签: angular angular2-routing angular2-router


    【解决方案1】:

    为 RC5 更新

    您可以从RouterState 获取所有已激活的路由(与主出口关联),而不是从当前 URL 开始并尝试从该 URL 获取路由:

    在每个成功的导航生命周期结束后,路由器都会构建一棵ActivatedRoutes 的树,它构成了路由器的当前状态。我们可以使用Router 服务和routerState 属性从应用程序中的任何位置访问当前的RouterState

    路由器状态为我们提供了从任何激活的路由向上和向下遍历路由树的方法,以从父路由、子路由和兄弟路由获取我们可能需要的信息。 -- reference

    订阅路由器事件,然后,在每个NavigationEnd 事件之后,从root 向下走ActivatedRoutes 的树:

    import { Component } from '@angular/core';
    import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
    import 'rxjs/add/operator/filter';
    
    @Component({
      selector: 'breadcrumbs',
      template: `
      <div>
        breadcrumbs: 
        <span *ngFor="let breadcrumb of breadcrumbs; let last = last">
          <a [routerLink]="breadcrumb.url">{{breadcrumb.label}}</a>
          <span *ngIf="!last">></span>
        </span>
      </div>`
    })
    export class BreadcrumbsComponent {
      breadcrumbs: Array<Object>;
      constructor(private router:Router, private route:ActivatedRoute) {}
      ngOnInit() {
        this.router.events
          .filter(event => event instanceof NavigationEnd)
          .subscribe(event => {  // note, we don't use event
            this.breadcrumbs = [];
            let currentRoute = this.route.root,
                url = '';
            do {
              let childrenRoutes = currentRoute.children;
              currentRoute = null;
              childrenRoutes.forEach(route => {
                if(route.outlet === 'primary') {
                  let routeSnapshot = route.snapshot;
                  console.log('snapshot:', routeSnapshot)
                  url += '/' + routeSnapshot.url.map(segment => segment.path).join('/');
                  this.breadcrumbs.push({ 
                    label: route.snapshot.data.breadcrumb,
                    url:   url });
                  currentRoute = route;
                }
              })
            } while(currentRoute);
          })
      }
    }
    

    路线如下所示:

    { path: '', component: HomeComponent, data: {breadcrumb: 'home'}}
    

    Plunker - RC.5,路由器 3.0.0-rc.1


    另请参阅https://stackoverflow.com/a/38310404/215945 以获得类似的解决方案。

    【讨论】:

    • 我构建了一个更完善的版本,请查看:github.com/alalonde/ng2-breadcrumbs
    • 我不禁认为这对于像面包屑这样简单的东西来说是非常丑陋的解决方案。
    • @hendrix,它很复杂/丑陋,因为正如 allonde 在他的 github 存储库中提到的那样,“您的导航层次结构可能与 URL 中的斜杠不直接匹配”。
    • 你有错吗?也许应该有 if(route.outlet === PRIMARY_OUTLET) 而不是 ...=== 'primary' 。 @hendrix 建议
    • @tazotodua 是的。自编写此答案以来,字符串值 primary 可能已更改。
    【解决方案2】:

    到目前为止,最可行的解决方案是(完成):

    • 使路线可导出/可导入
    • 从 router.events subscribe 获取当前 url 更新
    • 在更改 url 时,循环路由路径,查看模式是否与 url 匹配
    • 如果patter与url匹配,则从匹配的路由中获取数据

    优点:工作

    缺点:在不使用 ng2 路由器的情况下手动重做 url-route 识别

    【讨论】:

      【解决方案3】:

      任何面包屑解决方案都必须处理 -

      1. 在应用程序路由中定义面包屑的声明式方法。
      2. 使用来自服务器响应的标签更新任何路由的动态异步方式。
      3. 在面包屑中跳过特定路线的方法。

      我创建了一个 Angular 库来处理所有这些问题,称为 xng-breadcrumbs - https://github.com/udayvunnam/xng-breadcrumb

      请随意查看,开发的一个 Angular 应用程序显示了面包屑的使用 - https://xng-breadcrumb.netlify.com

      Angular 库规划、创建、持续发布很好documented in this medium article

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-07
        • 1970-01-01
        • 1970-01-01
        • 2016-09-05
        相关资源
        最近更新 更多