Angular 带有延迟加载模块的路由器面包屑
Angular Router Breadcrumbs with Lazy Loaded Modules
我正在使用 Angular 路由器动态添加面包屑。我遵循了几个示例并使它们成功运行。
但是,如果我尝试合并延迟加载的模块,我会收到错误消息:
Root segment cannot have matrix parameters
我已经研究过那个问题,但未能找到令人满意的 information/fixes。
我已经创建了一个 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 {}
我发现了与该问题有关的几个因素,并将其付诸 'seemingly' 工作:
您的方法 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
路径就是你在他的模块中的注册组件。路由就能正确注册了。
感谢 Robert、Alex Beugnet 和 DAG 的评论,让我走上正确的轨道,找到可靠的解决方案!
最后的内容在这里: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/仿制药/纸巾
我正在从事的项目只需要一个参数...永远。
最后,我能够处理立即加载的路由和延迟加载的路由,这是我的最终目标。我确信有些情况我没有考虑到,但我觉得它非常可靠。
无论如何,我鼓励人们接受这里的东西 运行。给我发一条有任何更新的便条,这样我就能知道这还能变成什么!谢谢!
我正在使用 Angular 路由器动态添加面包屑。我遵循了几个示例并使它们成功运行。
但是,如果我尝试合并延迟加载的模块,我会收到错误消息:
Root segment cannot have matrix parameters
我已经研究过那个问题,但未能找到令人满意的 information/fixes。
我已经创建了一个 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 {}
我发现了与该问题有关的几个因素,并将其付诸 'seemingly' 工作:
您的方法
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
路径就是你在他的模块中的注册组件。路由就能正确注册了。
感谢 Robert、Alex Beugnet 和 DAG 的评论,让我走上正确的轨道,找到可靠的解决方案!
最后的内容在这里: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/仿制药/纸巾
我正在从事的项目只需要一个参数...永远。
最后,我能够处理立即加载的路由和延迟加载的路由,这是我的最终目标。我确信有些情况我没有考虑到,但我觉得它非常可靠。
无论如何,我鼓励人们接受这里的东西 运行。给我发一条有任何更新的便条,这样我就能知道这还能变成什么!谢谢!