8

给定一个 URL,例如/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 的每个段)上所有参数的结果集。

我可以通过例如拆分段中的 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% 不受保护(显示给所有人)。因此,在导航菜单级别(在 之外router-outlet)我只想显示与当前用户相关的链接,所以我需要知道哪些路线受到警卫的保护。警卫/数据/任何东西只是问题的一个特例。

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

这有可能吗?

4

2 回答 2

6

在 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。要么是因为 url 错误,要么是您使用异步路由 viaLoadChildren并且路由尚未加载。即使使用异步路由,面包屑也能很好地使用它。如果您使用它来检查权限,例如通过指令,则需要注意是否使用异步路由。

于 2017-04-09T08:33:25.020 回答
3

还有另一种获取路由数据配置的方法。它涉及了解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]);
}

此外,如果您知道您的 url 段,您甚至可以匹配它以获取特定路径的配置:

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 服务上的一个函数来检查用户是否具有使用数据字段中列出的权限的权限。我还可以使用身份验证服务中的相同功能来隐藏我的主菜单中的链接*ngIf="authSvc.CheckPermission(permission1)等。这样我就不必在任何地方复制逻辑。最终,API 端点也应该受到服务器端的保护。

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

于 2017-03-31T15:24:11.923 回答