angular - Angular 8 边缘案例:ActivatedRoute#data 上的奇怪值(在父级上解析,在子级上的数据 => 子级数据被覆盖)
问题描述
我在实现一个简单的面包屑组件时偶然发现了这个问题。
这个想法是breadcrumb
在路线的data
属性上附加数据。对于静态值,效果很好:
const routes: Route[] = [
// ...
{ path: 'outer', data: { breadcrumb: 'outer' }, component: OuterComponent, children: [
{ path: '', pathMatch: 'full', data: { breadcrumb: 'inner' }, component: InnerComponent }
] }
// ...
];
这给了我'outer'
和'inner'
对应ActivatedRoute
的s。
对于动态值,解析器服务似乎是一个很好的解决方案。如果不是一个(奇怪的?)边缘情况,这也很有效:
const routes: Route[] = [
// ...
{ path: 'outer', resolve: { breadcrumb: OuterResolverService }, component: OuterComponent, children: [
{ path: '', pathMatch: 'full', data: { breadcrumb: 'inner' }, component: InnerComponent }
] },
// ...
];
这给了我'outer'
和'outer'
(再次)对应ActivatedRoute
的 s。这让我很惊讶。
注意:当内部组件有任何路径但
''
.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 演示了该问题: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
推荐阅读
- laravel - 删除不适用于针对 API 的 Vue 路由
- windows - 启动 git bash 给出错误“bash: fork: retry: No child processes”
- ios - 什么时候在没有可见函数调用的程序中调用 swift 函数?
- java - 如何将列表转换为唯一列表?
- android - 如何使用 AdapterViewFlipper 检测 clicklistner 和 guesture
- amazon-s3 - 如何处理从云端下载的浏览器缓存
- spring-data-jpa - 带有@OneToMany 的 JPA EmbeddedId - 无法使用 JOIN 进行查询
- firebase - 如果某人的数据不包含特定密钥,我如何防止他写?
- javascript - 页面加载后,Jquery,Django,Infinite Scroll 加载其余元素
- html - 将项目与对齐内容对齐