【问题标题】:Using the Angular router how do I share routes across multiple named outlets使用 Angular 路由器,我如何在多个命名出口之间共享路由
【发布时间】:2019-03-20 13:28:57
【问题描述】:

我有一个应用程序,我想在应用程序的多个位置显示同一组组件/路由。想想像多个面板或侧边栏这样的东西,用户可以根据他们选择的内容在多个位置显示相同的组件。

例如,用户可能想要“在侧面板中显示状态组件”或“在页面右下面板中显示状态组件”。

(在我的例子中,出口的数量是固定的,但同样的概念可以用于仪表板风格的 UI,它具有动态数量的卡片,每个卡片都有一个加载组件的路径)

我的想法是为此使用带有命名插座的角度路由器。这将允许轻松重用支持动态创建的组件,并将当前路由状态保留在 URL 中以便于重新加载。

例如,一个 url 可能看起来像:

https://.../app(side:status_comp//popup:other_comp)

我已经命名了出口,但我不知道如何在多个命名出口之间重用路由,而不在路由器配置中复制路由。

例如:

const appRoutes: Routes = [
  { path: 'main', component: AppComponent },  

  // ==> Have to repeat each route for each outlet name
  { path: 'comp_a', component: CompA, outlet: 'first' },  
  { path: 'comp_b', component: CompB, outlet: 'first' },  
  { path: 'comp_a', component: CompA, outlet: 'second' },  
  { path: 'comp_b', component: CompB, outlet: 'second' },   

  // ==> Would like to just do this
  /*
  { path: 'comp_a', component: CompA},  
  { path: 'comp_b', component: CompB},  
  */

  { path: '', redirectTo: '/main', pathMatch: 'full' },
  { path: '**', redirectTo: '/main' }
];

简化模板:

<p>Outlet 1</p>
<a [routerLink]="[{ outlets: { first: ['comp_a'] } }]">Comp A</a>
<a [routerLink]="[{ outlets: { first: ['comp_b'] } }]">Comp B</a>

<div class="outlet-wrapper">    
  <router-outlet name="first"></router-outlet> 
</div>

<p>Outlet 2</p>
<a [routerLink]="[{ outlets: { second: ['comp_a'] } }]">Comp A</a>
<a [routerLink]="[{ outlets: { second: ['comp_b'] } }]">Comp B</a>

<div class="outlet-wrapper">  
   <router-outlet name="second"></router-outlet>
</div>

然后使用以下命令将组件路由到出口:

this.router.navigate([{outlets: {first: ['comp_a']}}]);

我想要的只是设置一个路由到给定组件的路由器,然后能够使用任何定义的路由调用router.navigate,但告诉它在指定的出口中加载该路由。

有没有办法做到这一点。

这是一个关于 stackblitz 的示例,我已经完成了所有设置。 ng-router-reuse app

我要进行的更改如上所示,在路由定义中也是如此。

有什么想法吗?

注意:我知道我可以使用 Angular CDK 中的 Portals 之类的东西并动态加载组件。这样做的问题是,用户所看到的状态不会存储到 URL 中以由路由器管理,并且它还阻止了路由器延迟加载的使用。

【问题讨论】:

  • 为什么要为此使用 angular-router?你不能用ComponentFactoryResolver之类的东西吗?
  • @Luxor001 我可以,这就是我过去所做的。它不允许的两件事是延迟加载或组件,以及在 URL 中保持显示组件的当前状态,以便人们可以重新加载或共享链接。所以目前正在尝试使用路由器,因为它看起来似乎是为某些此类事情设计的。

标签: angular angular-router


【解决方案1】:

看起来您可以在运行时动态更新路由器配置,在导航时。这是一个例子。 https://stackblitz.com/edit/ng-router-reuse-c7j96a

这里有一个简短的解释。

1) 在链接或按钮上单击在路由器配置中查找路由。

 let route = this.router.config.filter(r => r.path === 'comp_a' && r.outlet === 'second')[0];

2) 如果路由不存在,则将其添加到配置中。

if(!route){
  this.router.config.unshift({path:'comp_a',outlet:'second',component:CompA})
}

我们在这里使用的是 unshift 方法而不是 push,因为我们不想在最后添加新的路由。我们总是希望将** 保留为最后一条路线。

3) 然后简单地导航到路线。

this.router.navigate([{outlets: {second: ['comp_a']}}]);

当应用程序已加载时,此解决方案会很有帮助。但是,如果您尝试加载具有命名出口路径的 URL,并且如果该路由未在路由器配置中定义,则会引发错误。

要克服这种情况,您可以在模块级别监听 NavigationStart 事件,然后您可以检查 URL 并相应地添加路由。虽然可以做到,但我觉得它不干净。我希望这会有所帮助。

【讨论】:

  • 很好的解决方案。希望我自己能想到那个。谢谢。
  • 我很高兴您喜欢这个解决方案,并且您总是可以通过投票来感谢答案。谢谢你:)
猜你喜欢
  • 2017-09-18
  • 1970-01-01
  • 2018-02-10
  • 2020-08-27
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 2016-10-28
  • 2023-03-12
相关资源
最近更新 更多