创建带有可选子项的路由

Creating a route with optional children

是否可以用 children 配置 "terminal" 路由,或者换句话说,用 "optional" children 配置路由。

我正在尝试创建一个可路由的 master/detail 视图,其中最初不显示详细信息,并且在打开详细信息视图时列表不会被破坏。

例如,导航到/a,然后在不破坏a的情况下,导航到/a/1

第一次尝试:

const routes: RouterConfig = [
  //...
  { path: 'a', component: AListComponent, children: [
    { path: ':id', component: ADetailsComponent }
  ]},
  //...
];

...使用此配置,将引发以下错误:

EXCEPTION: Error: Uncaught (in promise): Error: Cannot match any routes: 'a'

第二次尝试

const routes: RouterConfig = [
  //...
  { path: 'a', component: AListComponent },
  { path: 'a', component: AListComponent, children: [
    { path: ':id', component: ADetailsComponent }
  ]},
  //...
];

...列表组件被销毁并重新创建,即如果它有用户输入,则值会消失。

第三次尝试 - 创建一个"Empty"组件并默认加载它。

const routes: RouterConfig = [
  //...
  { path: 'a', component: AListComponent, children: [
    { path: '', component: EmptyComponent },
    { path: ':id', component: ADetailsComponent }
  ]},
  //...
];

... 有效,但感觉像是一种解决方法。

有没有更好的方法?

在我看来,最好的方法是不显示您第三次尝试中显示的任何内容的空虚拟组件。

第三次尝试的一个更简单的版本是简单地使用一个空路径,其中没有任何其他内容,甚至没有组件:

const routes: Routes = [
  { path: 'a', component: AListComponent, children: [
    { path: '' },
    { path: ':id', component: ADetailsComponent }
  ]},
];

Victor Savkin 有 written about componentless routes,尽管他并没有像这样使用完全空的路线(他的示例包含 redirectchildren 属性).

根据您的设置,您甚至可以更进一步删除 /a 路径。我在功能模块中有一个像这样的 routes 声明,在 path: 'module-path':

下延迟加载
const routes: Routes = [
  { path: '', component: AListComponent, children: [
    { path: '' },
    { path: ':id', component: ADetailsComponent }
  ]},
];

所以路由到 /module-path 会加载包含空 <router-outlet> 的 AListComponent,路由到 /module-path/5 会使用 ADetailsComponent 填充出口。