首页 > 解决方案 > 设置路由以定位命名来自组件的模板,而不是来自 AppComponent 的模板

问题描述

动机

我的 Angular 应用程序中需要多个布局模板:一个用于身份验证相关组件的空模板、一个带有用于特定于应用程序导航的菜单栏的模板以及一个向菜单栏添加侧边栏的模板。将侧边栏作为命名的路由器插座会很有帮助。

这是问题的演示/简化:假设TwoOutletsComponent有一个<router-outlet name="seconde" />命名路由器,我想要这个链接:/two/one(second:forsecond)加载我的TwoOutletsComponent,在未命名的路由器中加载一些内容,然后/forsecond在“第二个”命名路由器出口中加载。激活该链接时,DOM 在逻辑上应该如下所示:

<AppComponent>
  <AppComponent's router-outlet>    
    <TwoOutletsComponent>
      <router-outlet named="sidebar>[content from /forsecond]</router-outlet>
      <router-outlet>[content from /two/one]</router-outlet>
    <TwoOutletsComponent>

鉴于上面的逻辑视图,我可以/two/one在未命名的路由器插座中很好地加载内容,但内容/forsecond不显示;控制台中未显示任何错误,启用路由器跟踪表明/forsecond路由已正常解析。

另一方面,如果我<router-outlet name="second" />在 AppComponent 中放了一个,那么它/forsecond会加载得很好——只是不是我想要的!这种情况下的逻辑视图如下所示:

<AppComponent> / <-- this gets loaded by default
  <AppComponent's router-outlet>    
    <TwoOutletsComponent>
      <router-outlet>[content from /two/one]</router-outlet>
    <TwoOutletsComponent>
  <AppComponent's second router-outlet>[content from /foresecond]</router-outlet>

我的相关路线如下所示:

const routes: Routes = [
  { ... other routes not included },
  {
    path: "two", component: TwoOutletsComponent,
    children: [      
      { path: "one", component: PlainTextComponent }
    ]
  },
  { 
    path: "forsecond", 
    pathMatch: "full", 
    component: PlainTextComponent, 
    outlet: "second" 
  }
]

我认为正在发生的事情:

我认为 Angular 的路由器以无上下文的方式处理所有路由,包括辅助路由。如果确实如此,那么在 AppComponent 的模板中寻找“第二个”路由器插座是有意义的。我希望以某种方式向路由器提示目标路由器插座将在 TwoOutletsComponent 的模板中找到,而不是在 AppComponent 的模板中。

在尝试提示路由器时,我尝试按顺序模仿用于主要内容的 Route,但结果是相同的,没有显示内容:

我已经建立了一个 Stackblitz 以希望清楚地说明这一点: 链接到 Stackblitz

标签: angularangular2-routingangular7router-outlet

解决方案


我已经将此问题追踪到我认为 Angular 路由器找到命名出口的方式中的一个错误:即使那些路由器构造了具有当前视图的完整层次结构的树状结构,命名出口也只会被搜索在第一级。我认为这是一个错误,我认为路由器应该遵循“主要”出口并递归搜索正确命名的出口。

我已经在 github 上提交了一个修复;如果它被接受(确认这确实是一个错误而不是“功能”),我将删除该问题。如果它没有被接受,我会保留这个问题(并修改这个答案)。

https://github.com/angular/angular/pull/27262


推荐阅读