我正在使用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 {}
感谢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;
}
有了所有好东西,有一个问题:你必须有一个适合每个参数的路线。
例如,如果您有网址:#/ 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 / Generic / Tissue
我正在进行的项目只需要我有一个参数......永远。
最后,我能够处理立即加载的路由和延迟加载的路由,这是我的最终目标。我确信有些情况我没有考虑过,但我觉得它非常可靠。
无论如何,我鼓励人们把这里的东西拿走并运行它。用任何更新给我拍一张便条,这样我就能做到这一点!谢谢!
我发现了与该问题有关的几个要素,并让它“看似”工作:
getBreadcrumbs()
在单个导航上被调用3次,这是一个问题。只需在函数的开头添加一个console.log('I pass !');
即可查看。SignUpModule
的空路径。这是因为你的breadcrumb组件将使用当前激活的路径为空('')的路径,并且会有效地破坏路由,因为你没有任何东西连接/
。更改组件中的这个部分将使它第一次工作,因为到延迟加载的模块路径的路由将被注册,并且它将能够注册非空的routerLink。breadcrumb.component.ts
let routeURL = child.snapshot.url.map(segment => segment.path).join('/');
if(routeURL.length == 0) {
routeURL = 'toto';
}
url += `/${routeURL}`;
/signup
路径适用于其模块中的注册组件。该路线将能够正确注册。