我有一个应用程序,我想在应用程序的多个位置显示相同的组件/路由集。想想多个面板或侧边栏,用户可以根据他们选择的内容在多个位置显示相同的组件。
例如,用户可能想要“在侧面板中显示状态组件”或“在页面右下方的面板中显示状态组件”。
(在我的情况下,出口的数量是固定的,但相同的概念可以用于具有动态数量的卡的仪表板样式UI,每个卡都有一个用于加载组件的路径)
我的想法是使用带有命名插座的角度路由器。这样可以轻松重用支持动态创建的组件,并将当前路由状态保留在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中,而且还会阻止使用路由器延迟加载。
看起来您可以在导航时在运行时动态更新路由器配置。这是一个例子。 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方法而不是推送,因为我们不想在最后添加新路由。我们总是希望将**
作为最后的路线。
3)然后只需导航到路线。
this.router.navigate([{outlets: {second: ['comp_a']}}]);
当应用程序已加载时,此解决方案可能会有所帮助。但是,如果您尝试加载具有指定插座的路径的URL,并且如果路由器配置中未定义该路由,则会引发错误。
要克服这种情况,您可以在模块级别监听NavigationStart事件,在那里您可以检查URL并相应地添加路由。虽然有可能这样做但对我来说并不干净。我希望这将有所帮助。