【问题标题】:Angular: resolve all route segments configuration by URLAngular:通过 URL 解析所有路由段配置
【发布时间】:2017-08-25 21:34:35
【问题描述】:

给定一个 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' } },
  ] }
] },

我需要找到所有段的实际配置,以便获得所有级别(url 的每个段)上所有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);

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

示例:假设我有 50% 的 URL 受到一些保护(例如,只有登录的用户可以访问)而其他 50% 没有受到保护(显示给所有人)。因此,在导航菜单级别(router-outlet 之外)我只想显示与当前用户相关的链接,因此我需要知道哪些路线受到警卫的保护。 Guards/data/whatever 只是问题的一个特例。

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

这有可能吗?

【问题讨论】:

  • smnbbrv 您的帖子中有什么 url 变量?你在哪里定义的?请回复。

标签: angular typescript angular2-router


【解决方案1】:

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

【讨论】:

    【解决方案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]);
    }
    

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

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

    【讨论】:

    • 这是真的,如果你只需要获取当前激活的路由的数据就可以了。我的问题是我只有一个与当前路由无关的 URL;我不想激活 URL,但我想知道如果我要激活这个 URL 将会发生什么配置
    • 在问题中添加了一个示例以澄清这一点
    • 您在编辑中的解决方案正是我想要避免的。我不想分别关心路由权限和链接权限。尽管您重用了该功能,但您仍然在重复权限,因此您需要记住在两个地方进行更改。我希望菜单自动了解哪个链接被禁止。
    • 对。这就是权限在前端和后端之间同步的原因。或者您创建一个导出的常量,因此没有任何“神奇”字符串。
    • 如果您找到更好的解决方案,请在此处发布作为答案。
    猜你喜欢
    • 2019-05-30
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多