使用Angular路由器如何在多个命名出口之间共享路由 [英] Using the Angular router how do I share routes across multiple named outlets

查看:101
本文介绍了使用Angular路由器如何在多个命名出口之间共享路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,希望在该应用程序的多个位置显示相同的一组组件/路线.考虑多个面板或侧栏之类的东西,用户可以根据选择内容在多个位置显示相同的组件.

I have an application where I want to show the same set of components / routes in multiple places in the application. Think something like multiple panels or side bars where the user can show the same components in multiple locations depending upon what they select.

例如,用户可能希望在侧面板中显示状态组件"或在页面的右下方面板中显示状态组件".

For example the user may want to "show the status component in side panel" or "show the status component in bottom right panel on page".

(在我的情况下,插座的数量是固定的,但是对于具有动态数量的卡的仪表板样式的UI可以使用相同的概念,每张卡都有要加载组件的路线)

(In my case the number of outlets is fixed, but the same concept could be used for a dashboard style UI with a dynamic number of cards that each have a route for the component to load)

我的想法是将带角度的路由器与命名插座配合使用.这样可以轻松重用支持动态创建的组件,并将当前路由状态保留在URL中以方便重新加载.

My idea was to use the angular router with named outlets for this. That would allow for easy reuse of components supporting dynamic creation as well as keeping the current routing state in the URL for easy reloading.

例如,URL可能类似于:

So for example a url may look like:

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

我已经命名了出口,但是我不知道该怎么做,是在多个命名出口之间重用路由,而无需在路由器配置中复制路由.

I have named outlets working, but what I can't figure out how to do is to reuse a route across multiple named outlets without duplicating the route in the router config.

例如:

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>

然后使用以下方法将组件路由到插座中:

Then route the component into the outlet using:

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

我要设置的是将路由器设置为给定组件的一条路由,然后可以使用任何已定义的路由调用router.navigate,但告诉它将该路由加载到指定的插座中.

What I would like is to just set the router with a single route to the given component and then be able to call router.navigate with any defined route but tell it to load that route in the named outlet.

有没有办法做到这一点.

Is there any way to do this.

这是stackblitz上的一个示例,在此示例中,我进行了所有设置. ng-router-reuse应用

Here is a sample on stackblitz where I have everything setup. ng-router-reuse app

我要进行的更改显示在上方,并且在路由定义中也是如此.

The change I want to make is shown above and in the same in the route definitions.

有什么想法吗?

注意:我知道我可以使用Angular CDK中的Portal之类的东西并动态加载组件.但是,问题在于,用户看到的状态不会存储到URL中以由路由器进行管理,并且还阻止了路由器的延迟加载.

Note: I know I could use something like Portals from the Angular CDK and dynamically load the components. The problem with that though is that the state of what the user is seeing doesn't get stored into the URL to manage by the router and it also prevents the use of router lazy loading.

推荐答案

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

It looks like you can update router configs dynamically at runtime, at the time of navigation. Here is an example. https://stackblitz.com/edit/ng-router-reuse-c7j96a

这是一个简短的解释.

1)在链接或按钮上,单击以在路由器配置中找到路由.

1) On link or button click find the route in the router config.

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

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

2) if the route does not exist add it to the configuration.

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

我们使用的是unshift方法,而不是此处的推送,因为我们不想在末尾添加新路线.我们始终希望保留**作为最后一条路线.

we are using unshift method and not the push here because we don't want to add new route at the end. We always want to keep ** as the last route.

3)然后只需导航至路线即可.

3) Then simply navigate to the route.

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

已经加载了应用程序时,此解决方案可能会有所帮助.但是,如果您尝试加载的URL的路径名为出口,并且该路由未在路由器配置中定义,则会抛出错误.

This solution can be helpful when the application is already loaded. But if you try to load a URL which has a path with a named outlet and if that route is not defined in the router configuration it will throw an error.

要克服这种情况,您可以在模块级别监听NavigationStart事件,然后可以在其中检查URL并相应地添加路由.尽管可以做到,但对我来说并不干净.我希望这会有所帮助.

To overcome that situation you can listen to the NavigationStart event at the module level and there you can examine the URL and add routes accordingly. Though it is possible to do it does not feels clean to me. I hope this will help.

这篇关于使用Angular路由器如何在多个命名出口之间共享路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆