角度8边缘情况:ActivatedRoute#data上的值很奇怪(在父级上解析,在子级上的数据=>子级数据被覆盖)

问题描述 投票:0回答:1

我在实现一个简单的面包屑组件时偶然发现了这个问题。

想法是在路由的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 angular8 angular-router
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.