我在实现一个简单的面包屑组件时偶然发现了这个问题。
想法是在路由的breadcrumb
属性上附加data
数据。对于静态值,效果很好:
const routes: Route[] = [
// ...
{ path: 'outer', data: { breadcrumb: 'outer' }, component: OuterComponent, children: [
{ path: '', pathMatch: 'full', data: { breadcrumb: 'inner' }, component: InnerComponent }
] }
// ...
];
这给了我'outer'
和'inner'
对应的ActivatedRoute
。
对于动态值,解析器服务似乎是一个很好的解决方案。如果不是(很奇怪?)边缘情况,那也行得通:
const routes: Route[] = [
// ...
{ path: 'outer', resolve: { breadcrumb: OuterResolverService }, component: OuterComponent, children: [
{ path: '', pathMatch: 'full', data: { breadcrumb: 'inner' }, component: InnerComponent }
] },
// ...
];
这再次给了我'outer'
和'outer'
对应的ActivatedRoute
。这让我感到惊讶。
注:当内部组件具有除
''
以外的任何路径时,它确实可以按预期工作。pathMatch: 'full'
似乎不是一个影响因素。我发现以下配置是一种可行的解决方法:{ path: 'outer', resolve: { breadcrumb: 'outer' }, component: OuterComponent, children: [ { path: 'inner', data: { breadcrumb: 'inner' }, component: InnerComponent }, { path: '', pathMatch: 'full', redirectTo: 'inner' } ]}
仍然,它让我感到奇怪:
是我误解了data
/ resolve
机制的工作原理吗? (在我看来,从官方文档看,这应该是预期的用例,但显然它没有按我认为的那样工作。)
这是预期的行为吗?
或者这是Angular 8中的错误吗?
供参考,一个展示问题的堆叠闪电:Stackblitz
Angular提供2种路由参数继承模式,默认值为emptyOnly
,这意味着只有空路径才能继承其父参数(参数包括数据和已解析的数据)。 (另一种模式是always
,这意味着孩子总是继承父级参数,这对您没有帮助)
在这种情况下,您的子路径为空,因此它正在继承其父参数,但是,通常,如果子数据具有匹配的键,则子数据应优先于继承的数据,就像在静态数据情况下一样。] >
但是问题是,解析数据始终覆盖静态数据,无论是否继承(如果出于某种原因,如果静态数据和解析数据在同一路径上具有相同的键,则静态数据将被覆盖),因此解析后的数据将被覆盖在已解析的父数据情况下,数据将覆盖子数据,但在静态情况下不会覆盖。或者,如果您在两个级别上都有解析器,则子级的解析数据将优先。
因此,这不是“错误”,而是一种古怪/怪异的行为。也许值得以角度提出,因为优先顺序似乎是:子级解析数据,父级解析数据,子级数据,父级数据...在什么时候(对我而言):子级解析数据,子级数据,父级解析数据,父数据。尽管我可以以任何方式看到争论,因为孩子在技术上继承了父母解析的数据,应该可以覆盖任何静态数据。
解决方法起作用,因为从技术上来讲,您的子路径不是空路径。您只是在欺骗路由器,不允许孩子继承。
您可以使用的略有不同的解决方法是,仅使用不同的关键字,并对感兴趣的面包屑组件进行检查,如下所示:
{ path: 'not-working', component: OuterComponent, resolve: { resolvedBreadcrumb: OuterResolverService }, children: [ { path: '', pathMatch: 'full', component: InnerComponent, data: { breadcrumb: 'inner' } } ] },
和:
const crumb = route.snapshot.data['breadcrumb'] || route.snapshot.data['resolvedBreadcrumb'];
其工作原理如下:https://stackblitz.com/edit/angular-pmw6x1?file=src%2Fapp%2Fapp.module.ts