【问题标题】:Angular Router Breadcrumbs with Lazy Loaded Modules带有延迟加载模块的角路由器面包屑
【发布时间】:2018-02-16 12:32:02
【问题描述】:

我正在使用 Angular 路由器动态添加面包屑。我遵循了几个例子,并让它们成功地工作。

但是,如果我尝试合并一个延迟加载的模块,我会收到错误:

Root segment cannot have matrix parameters

我已研究过该问题,但未能找到令人满意的信息/修复方法。

我已经创建了一个 plunk,其中包含我想要完成的内容,以便从该页面上的大量代码中保存: https://plnkr.co/edit/505x2r

如何继续使用路由器创建的动态面包屑导航,但同时使用延迟加载的路由。

import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';

import { RootComponent } from 'src/root/root.component';
import { IndexComponent } from 'src/index/index.component';
import { SignupComponent } from 'src/signup/signup.component';
import { SigninComponent } from 'src/signin/signin.component';

@NgModule({
    imports: [
        RouterModule.forChild([
            {
            path: '',
            component: RootComponent,
            children: [
                {
                    path: 'signin',
                    loadChildren: 'src/signin/signin.module#SigninModule'
                },
                {
                    path: 'signup',
                    component: SignupComponent,
                    data: {
                        breadcrumb: 'Sign Up'
                    }
                },
                {
                    path: '',
                    component: IndexComponent
                }
            ]
        }
    ])
],
exports: [
    RouterModule
]
})
export class RootRoutingModule {}

【问题讨论】:

  • in signin-routing.module.ts :将空路径更改为重定向使其工作而不会中断:{ path: '', redirectTo: 'signin', pathMatch: 'full' },,但路由名称加倍:/#/signin/signin
  • 检查我所做的更改。它仍然不正确,但我可以跟踪问题,然后您可以继续:plnkr.co/edit/KTE39A?p=preview 不要从 plunker 复制并粘贴此代码,因为我更改了一些内容,只需在 html 的面包屑。我删除了路由器链接。您必须找到一种方法来解决异步模式下的路由器链接问题。
  • 我把这个做得更好一点:plnkr.co/edit/aOCxS2?p=preview

标签: angular angular-ui-router lazy-loading breadcrumbs


【解决方案1】:

感谢 Robert、Alex Beugnet 和 DAG 的 cmets 并让我走上正确的轨道,找到一个可靠的解决方案!

最后一击:https://plnkr.co/edit/iedQjH?p=preview

以下是我遇到的浓缩问题:

首先,我有延迟加载的路线,我在路线上以面包屑的形式获取数据。运行 getBreadcrumbs 时,面包屑标签会显示两次。我通过添加以下行解决了这个问题:

  if (
    child.snapshot.url.map(segment => segment.path).length === 0
  ) {
      return this.getBreadcrumbs(child, url, breadcrumbs);
  }

其次,我的路线只是一个参数输入,但我需要将其列在面包屑路径上。这已通过映射 child.snapshot.url 并将段分配给标签来解决。

const routeArray = child.snapshot.url.map(segment => segment.path);
for ( let i = 0; i < routeArray.length; i++ ) {
    label = routeArray[i];
}

第三,我需要显示下一个路由的参数和标签,无论它是立即加载还是通过模块延迟加载。我还遇到了以下需要拆分和适当分配标签的路径:

{
    path: ':id/products',
    loadChildren: 'src/products/products.module#ProductsModule',
    data: {
      breadcrumb: 'Products'
    }
}

                {
                  path: 'orders/:id',
                  component: OrderComponent,
                  data: {
                    breadcrumb: 'Orders'
                  }
                },

解决方案是:

  for ( let i = 0; i < routeArray.length; i++ ) {
    if ( Object.keys(child.snapshot.params).length > 0 ) {
      if ( this.isParam(child.snapshot.params, routeArray[i]) ) {
        label = routeArray[i];
      } else {
        label = child.snapshot.data[ROUTE_DATA_BREADCRUMB];
      }
    } else {
      label = child.snapshot.data[ROUTE_DATA_BREADCRUMB];
    }
    const routeURL = routeArray[i];
    url += `/${routeURL}`;
    const breadcrumb: BreadCrumb = {
      label: label,
      params: child.snapshot.params,
      url: url
    };
    breadcrumbs.push(breadcrumb);
  }

private isParam(params: Params, segment: string) {
  for ( const key of Object.keys(params)) {
    const value = params[key];
    if ( value === segment ) {
      return true;
    }
  }
  return false;
}

所有好东西都有一个问题:您必须为每个参数制定路线

例如,如果您有 url:#/quotes/123456/products/123456/Generic/Tissue,您将需要以下路由:

{
  path: ':id',
  component: ProductComponent,
  data: 'data'
},
{
  path: ':id/:make',
  component: ProductComponent,
  data: 'data'
},
{
  path: ':id/:make/:model',
  component: ProductComponent,
  data: 'data'
}

你最终会得到一个看起来像这样的可点击面包屑:

首页 / 报价 / 123456 / 产品 / 123456 / 通用 / 组织

我正在进行的项目只需要我有一个参数......永远。

最后,我能够处理立即加载的路由和延迟加载的路由,这是我的最终目标。我确信有些情况我没有考虑到,但我觉得它很可靠。

无论如何,我鼓励人们带着这里的东西跑。给我发一张有任何更新的便条,这样我就可以知道这还能变成什么!谢谢!

【讨论】:

  • 我试图应用这个答案,但是如果我希望我的路线是 Home/Quotes/Quote.. 我不想显示 id 而是用另一个描述性文本替换 - 我该怎么办?另外,如果我不想显示最后一个面包屑,我如何/在哪里可以更改代码?
  • 这个例子对我来说很好,但我有延迟加载模块,我想在从主页登录后显示面包屑。当我登录时面包屑显示正常,但在我刷新页面后面包屑不是出现然后我通过路由页面加载组件,我应该怎么做才能在刷新时显示面包屑??
  • @CodersCreed ,如果你有 stackblitz 演示,请分享。谢谢
【解决方案2】:

我发现了与该问题有关的几个因素,并让它“看似”起作用:

  • 您的方法 getBreadcrumbs() 在一次导航中被调用 3 次,这是一个问题。只需在函数开头添加console.log('I pass !'); 即可查看。

  • 我认为主要问题是您使用了延迟加载模块的路径。对于您的面包屑组件,它将使用您的 SignUpModule 中的空路径。这就是中断的原因,因为您的面包屑组件将使用当前激活的空路径 ('') 中的路径,并且将有效地中断路由,因为您将 / 连接到任何内容。更改组件中的这部分将使其第一次工作,因为到延迟加载模块路径的路由将被注册,并且它将能够注册一个非空的 routerLink。

breadcrumb.component.ts

   let routeURL = child.snapshot.url.map(segment => segment.path).join('/');
   if(routeURL.length == 0) {
     routeURL = 'toto';
   }
   url += `/${routeURL}`;  
  • 因此,您应该找到一种方法来为您的延迟加载模块使用空路由,以便/signup 路径用于您的模块中的注册组件。该路线将能够正确注册。

【讨论】:

    猜你喜欢
    • 2019-04-03
    • 2021-08-06
    • 2019-11-22
    • 1970-01-01
    • 2020-07-12
    • 2017-08-21
    • 2023-04-11
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多