Angular:按URL解析所有路径段配置

时间:2017-03-31 14:50:24

标签: angular typescript angular2-router

给定一个网址,例如/path/path2/path3/123;sdf=df和路由配置:

{ 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。

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);

我可以通过配置树来查找分段,找出我需要的分支,但它可能会导致麻烦,例如:同时针对:id段解析create。所以,我想使用路由器的解析配置的方式,如果内部路由器实现发生变化,我就不需要改变我的。

示例:想象我有50%的URL受到某些保护(例如,只有已登录的用户可以去那里),而其他50%的URL不受保护(为每个人显示)。因此,在导航菜单级别(router-outlet之外)我想只显示与当前用户相关的链接,因此我需要知道哪些路由受到保护。警卫/数据/其他只是问题的一个特例。

请不要坚持示例,我正在寻找获取特定网址配置集的常用方法。

这有可能吗?

2 个答案:

答案 0 :(得分:5)

使用版本2.x,您可以使用路由器内部使用的recognize功能将网址与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 })来处理promise的错误(识别或新的路由器方法)也是有意义的。它可能无法解析url-> routestatesnapshot。要么是因为url错误,要么是通过LoadChildren使用异步路由,并且路由尚未加载。即使使用异步路由,面包屑也可以很好地使用它。如果您使用它来检查权限,例如通过指令,则需要注意是否使用异步路由。

答案 1 :(得分:2)

还有另一种获取路由数据配置的方法。它涉及了解数据对象中的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%的URL受到保护   一些警卫(例如,只有登录用户可以去那里),其他50%是   不受保护(为每个人显示)。所以,在导航菜单上   级别(路由器插座外)我想只显示链接   这与当前用户有关,所以我需要知道哪个   路线受到警卫的保护。警卫/数据/无论是什么   特殊情况的问题。

我解决了隐藏链接的问题,未经身份验证的用户可以看到或隐藏未经授权的用户可能看到的链接的方法是在我的身份验证服务上创建一个功能,可以检查用户是否经过身份验证或授权。它与我的路线上的警卫也使用的功能相同。

例如,我可能在路由数据CheckPermissions的路由上有一个data: { permissions:[permission1, permission2] }保护。在后台,这个守卫使用auth服务上的一个功能来检查用户是否拥有使用列出的权限数据字段中的权限。我也可以使用auth服务中的相同功能来隐藏我的主菜单中的*ngIf="authSvc.CheckPermission(permission1)等链接。这样我就不必在任何地方复制逻辑了。最终,API端点也应该受到服务器端的保护。

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