2017-03-31 254 views
8

给定URL(例如, /path/path2/path3/123;sdf=df和路由配置:Angular:通过URL解析所有路由段配置

{ path: 'path', data: { g: 'h' }, children: [ 
    { path: 'path2', data: { c: 'd' }, children: [ 
    { path: 'something', component: TestpageComponent, data: { a: 'b' } }, 
    { path: 'path3/create', component: TestpageComponent, data: { b: 'c' } }, 
    { path: 'path3/:id', component: TestpageComponent, data: { b: 'c' } }, 
    ] } 
] }, 

我需要的是找出为了得到一个结果集的所有级别的所有data参数(URL的各段)的所有段的实际配置。

我可以通过例如分割段中的URL。

console.log(this.router.parseUrl(url)); 

或者更精确地说

console.log(this.router.parseUrl(url).root.children['primary'].segments); 

将返回

[{"path":"path","parameters":{}},{"path":"path2","parameters":{}},{"path":"and","parameters":{}},{"path":"123","parameters":{"sdf":"df"}}] 

所以,分裂URL成段是没有问题的。不过,我需要为每个细分市场进行配置。

我能得到的实际配置对所有路由与

console.log(this.router.config); 

我可以用段经过配置树,并找出我需要的分支,但它可以例如引起麻烦同时针对create分段解决:id。所以,我想使用路由器的解决方法,如果内部路由器实现更改,我不需要更改我的配置。例如:假设我有50%的URL受到某些警卫的保护(例如,只有登录的用户可以去那里),其他50%没有受到保护(为所有人显示)。因此,在导航菜单级别(router-outlet之外),我只想显示与当前用户相关的链接,因此我需要知道哪些路由受到警卫保护。警卫/数据/无论是这个问题的特殊情况。

请不要拘泥于示例,我正在寻找一种通用的方式来获取特定URL的配置集。

这无论如何可能吗?

回答

4

对于2.x版本,您可以使用路由器内部使用的recognize函数将url与RouteStateSnapshot匹配。

import { recognize } from '@angular/router/src/recognize'; 

recognize(null, this.router.config, this.router.parseUrl(url), url).subscribe(route => { 
    var routeSnapshot = route.root.firstChild; 

    // Go to all children to get actual route. 
    // If you use routes with children you should have 
    // the full tree here 
    var childSnapshot = routeSnapshot.firstChild; 
    while (childSnapshot != null) { 
     childSnapshot = routeSnapshot.firstChild; 
     if (childSnapshot != null) { 
      routeSnapshot = childSnapshot; 
     } 
    } 

    let routeData = routeSnapshot.data || {}; 

    // routeData['a']... 
}); 

不幸的是,这似乎不再适用于版本4.x.对于4.x版本,我创建了一个拉取请求,以向Router添加新方法来展示识别功能。

https://github.com/angular/angular/issues/15826

从另一个方面说明。通过添加.catch((rej) => { // some code if it fails to resolve route })来处理承诺的错误(识别或新的路由器方法)也是有意义的。可能会发生它无法解析url-> routestatesnapshot。无论是因为网址错误还是通过LoadChildren使用异步路由,并且路由尚未加载。即使是异步路由,面包屑也能很好地工作。如果您使用它来检查权限,例如通过指令,则需要注意是否使用异步路由。

1

还有另一种获取路由数据配置的方法。它涉及了解数据对象中的key属性。

在你的组件,你可以用

this.route.snapshot.data['key'] 

你可以得到母公司的数据和

this.route.snapshot.parent.data['key'] 

甚至用得到,准确的路由数据的祖父母的数据

this.route.snapshot.parent.parent.data['key'] 

由于您在所有路线上使用不同的钥匙,因此更加困难。在这种情况下,你需要拿到钥匙的列表,并遍历是:

let keys = Object.keys(this.route.snapshot.data); 
keys.map(x => { 
    console.log('key', x); 
    console.log('data', this.route.snapshot.data[x]); 
} 

另外,如果你知道你的网址片段,你甚至可以匹配,要得到特定路径的配置:

let configForRoute = this.router.config.find(x => x.path === this. route.snapshot.url.toString()) 

let dataForSegment = this.router.config.find(x => x.path === 'somePath').data['key'] 

粗解决方案,使所有你需要看起来像这样的数据:

obj = {}; 
getData(routeData){ 
    let keys = Object.keys(routeData); 
    keys.map(x => this.obj[x] = routeData[x]) 
} 

this.getData(this.route.snapshot.parent.parent.data); 
this.getData(this.route.snapshot.parent.data); 
this.getData(this.route.snapshot.data); 
console.log(obj); 

希望这有助于在正确的轨道上让你得到你所需要的数据。

编辑

我可能误解了原来的问题。

由于添加量:

为什么我需要吗?想象一下,我有50%的网址被 保护(例如,只有登录的用户可以去那里),而其他50%的网址是 没有保护(为所有人显示)。因此,在导航菜单 级别(路由器插座外部),我只想显示与当前用户相关的链接 ,因此我需要知道哪些路由受到警卫保护。警卫/数据/无论是只是一个 问题的特殊情况。

我躲在解决任何环节未经授权的用户可以看到或隐藏链接未经授权的用户可以看到这个问题的方法是建立在我的身份验证服务功能可以检查用户是否被认证或授权。这与我的卫兵在我的路线上使用的功能相同。

例如,我可以在我的路由的CheckPermissions后卫路线数据data: { permissions:[permission1, permission2] }幕后制作这Guard使用的身份验证服务的功能,以检查用户是否使用数据领域的上市许可权限。我也可以使用auth服务中的相同功能来隐藏我的主菜单中的链接,例如*ngIf="authSvc.CheckPermission(permission1)等。这样我就不必在任何地方复制逻辑。最终,API端点也应该受到服务器端的保护。

至于能够给路由器一个url并找回它匹配的路由而不导航到它,我无法找到一个记录的方式来做到这一点。希望这至少有一点帮助。

+0

这是真的,如果你只是需要获取当前激活的路线的数据,它的工作原理。我的问题是,我只有一个URL,与当前路线无关;我不想激活URL,但我想知道将要发生什么配置,如果我要激活这个URL – smnbbrv

+0

增加了一个例子来解释这个问题 – smnbbrv

+0

您的编辑解决方案正是我想要的避免。我不想单独关心路由权限和链接权限。尽管您重复使用了该功能,但您仍然需要复制权限,因此您需要记住在两处修改它。我想让菜单自动理解哪个链接被禁止。 – smnbbrv

相关问题