【问题标题】:How to elegantly get full url from the ActivatedRouteSnapshot?如何优雅地从 ActivatedRouteSnapshot 中获取完整的 url?
【发布时间】:2018-10-19 09:27:29
【问题描述】:

在我的一些 Angular 路由守卫中,我想设置“下一个”路径,以便在成功登录后重定向到。

所以,普通的守卫canActivate 函数签名是这样的:

public canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
  // ...blah
  return true;
}

route 参数是ActivatedRouteSnapshot 的一个实例。

以前为了获得“下一个”网址,我只是从route.url 获得的。只要没有子路线,这就可以正常工作。

我的示例 URL 是/search/advanced?query_hash=1221d3b57f5616ee16ce70fdc78907ab,其中advancedsearch 的子路由。

子路由可以在route.children 中找到,但是遍历这些子路由(尤其是可能有多个级别)并以这种方式组合 URL 看起来既尴尬又丑陋。

我感兴趣的是包含在route._routerState.url 属性中(是一个字符串,在下图的底部),但它是一个“私有”变量。

我错过了什么吗?如何优雅地从ActivatedRouteSnapshot 获得完整的(带有子路径)URL? Angular 版本是 5.1。

【问题讨论】:

    标签: angular angular-routing angular-router-guards


    【解决方案1】:

    Angular 路由器没有现成的函数来实现这一点,所以我写了它们:

    function getResolvedUrl(route: ActivatedRouteSnapshot): string {
        return route.pathFromRoot
            .map(v => v.url.map(segment => segment.toString()).join('/'))
            .join('/');
    }
    
    function getConfiguredUrl(route: ActivatedRouteSnapshot): string {
        return '/' + route.pathFromRoot
            .filter(v => v.routeConfig)
            .map(v => v.routeConfig!.path)
            .join('/');
    }
    

    route 来自 ProjectComponent 时的示例输出:

    const routes: Routes = [
        {
            path: 'project', component: ProjectListComponent, children: [
                {path: ':id', component: ProjectComponent}
            ]
        },
    ];
    getResolvedUrl(route) => /project/id1
    getConfiguredUrl(route) => /project/:id
    

    【讨论】:

    • @marc-j-schmidt 功能强大。我发现当您拥有带有子路由的功能模块时,.map 可以返回空字符串段。有点像你在数组中得到的第一个元素。所以数组可能看起来像['', 'manager', '', 'users'],导致resolvedUrl 看起来像/manager//users。我现在用.replace('//','/') 破解了它以进行重复数据删除。可能是 filter 以首先防止空字符串,并在最后的 resolvedUrl 前面加上 / 可能是更好的设计选择。有什么想法吗?
    • 是的,添加一个检查空路径的过滤器就足够了。
    • 这对我来说已经很长时间了——但现在我需要在有辅助路由时获取 URL。这种方法只是在没有括号的情况下将它们全部挤压在一起。不敢相信没有构建方式:-/
    【解决方案2】:

    试试这个从RouterStateSnapshot获取它

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
          console.log(state.url)
          ...
    

    【讨论】:

    • 这不回答问题,它说明了如何从“ActivatedRouteSnapshot”获取 URL。这个接口不仅用于canActivated(),而且在许多其他地方,例如shouldReuseRoute(route: ActivatedRouteSnapshot),你没有第二个参数'state'那么如何从ActivatedRouteSnapshot获取URL??
    • 是的,它对我有用 - window.location.origin + state.url
    • 虽然这没有回答问题,但它非常适合我正在寻找的东西。感谢您提出这个问题!
    【解决方案3】:

    Marc 的getResolvedUrl 的解决方案不返回查询参数。 下面的函数增加了对查询参数的支持。

    getResolvedUrl(route: ActivatedRouteSnapshot): string {
      let url = route.pathFromRoot.map((v) => v.url.map((segment) => segment.toString()).join('/')).join('/');
      const queryParam = route.queryParamMap;
      if (queryParam.keys.length > 0) {
        url += '?' + queryParam.keys.map(key => queryParam.getAll(key).map(value => key + '=' + value).join('&')).join('&');
      }
      return url;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      • 2011-06-13
      • 2017-04-22
      • 2014-07-04
      • 2019-04-08
      • 2012-04-28
      相关资源
      最近更新 更多