如何从ActivatedRouteSnapshot优雅地获取完整的URL?

Rad*_*iak 11 angular-routing angular angular-router-guards

在我的一些角度路线防护中,我想设置"下一个"路径,在成功登录后重定向到.

因此,oridinary guard canActivate功能签名如下所示:

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

route参数是ActivatedRouteSnapshot的实例.

以前要获得"下一个"URL我只是从它获得它route.url.只要没有儿童路线,这种方法就可以了.

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

可以找到子路由route.children,但迭代这些子路径(特别是可能有多个级别),并且这种方式组合URL似乎很尴尬和丑陋.

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

我错过了什么吗?如何才能优雅地从中获取完整的(带有儿童路径)网址ActivatedRouteSnapshot?Angular版本是5.1.

在此输入图像描述

Mar*_*idt 16

没有准备好使用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('/');
}
Run Code Online (Sandbox Code Playgroud)

例如当输出route是从ProjectComponent:

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

  • @marc-j-schmidt 功能很棒。我发现当你有带有子路由的功能模块时,“.map”可以返回空字符串段。有点像数组中的第一个元素。因此,该数组可能看起来像“['', 'manager', '', 'users']”,从而导致“resolvedUrl”看起来像“/manager//users”。我用 `.replace('//','/')` 来破解它以暂时删除重复数据。可能首先使用“过滤器”来防止空字符串,并在最终的“resolvedUrl”前面加上“/”可能是更好的设计选择。有什么想法吗? (2认同)
  • 这对我来说已经很长时间了 - 但现在我需要在有辅助路由时获取 URL。此方法只是将它们全部压缩在一起,而不使用括号。不敢相信没有构建方式:-/ (2认同)

Fat*_*med 6

尝试从RouterStateSnapshot获取它

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      console.log(state.url)
      ...
Run Code Online (Sandbox Code Playgroud)

  • 这没有回答这个问题,该问题说明了如何从“ ActivatedRouteSnapshot”获取URL。这个接口不仅可以在canActivated()中使用,还可以在许多其他地方使用,例如shouldReuseRoute(route:ActivatedRouteSnapshot),那里没有第二个参数“ state”,那么如何从ActivatedRouteSnapshot获取URL? (16认同)
  • 虽然这没有回答问题,但它非常适合我正在寻找的东西。感谢您提出这个! (6认同)
  • 由于问题询问的是“CanActivate.canActivate()”,因此这是问题问题的完美解决方案。问题标题不符合提出的问题。 (2认同)

小智 6

Angular 中已经有一个现成的函数可以实现createUrlTreeFromSnapshot

UrlTree首先,您现在可以仅从该方法返回canActivate。其次,如果你想将 URL 组成为字符串,你可以使用UrlSerializerAPI,它应该反映哈希与路径 URL 策略:

import { createUrlTreeFromSnapshot, UrlSerializer } from '@angular/router';

// ...

class MyClass {

    constructor(private urlSerializer: UrlSerializer) {}

    getResolvedUrl(route: ActivatedRouteSnapshot) {
        return this.urlSerializer.serialize(
            createUrlTreeFromSnapshot(route.snapshot, ['.'])
        );
    }
}
Run Code Online (Sandbox Code Playgroud)


Edw*_*ler 5

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;
}
Run Code Online (Sandbox Code Playgroud)