Angular CanActivate guard - createUrlTree 相对导航

Angular CanActivate guard - createUrlTree relative navigation

我目前有一个路由守卫,例如

export class EntityGuard implements CanActivate {
  constructor(private readonly router: Router, ...) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> {

  ...

此防护已激活 URL

basePath/select/10/123

这意味着

basePath/select/:type/:id

当满足某个条件时,我需要强制导航回到

basePath/select/:type

我如何使用 createUrlTree 做到这一点?例如

if (...) {
   return of(this.router.createUrlTree([../', type]));
}

我需要设置

{ relativeTo: parent }

选项。但是我似乎找不到办法。


我目前的解决方案是

private navigateBack(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  const end = state.url.indexOf(route.url[route.url.length - 1].path);
  const parentUrl = state.url.slice(0, end);
  return of(this.router.createUrlTree([parentUrl]));
}

我真的不喜欢。字符串操作对我来说很重要。

我遇到了同样的情况,得到了类似的解决方案。主要问题是如果我们使用构造函数注入 ActivateRoute ,我们会得到以前的路由。 他们计划在 canActivate 方法中传递 ActivateRoute 而不是 ActivatedRouteSnapshot.

这是门票: https://github.com/angular/angular/issues/22763

您可以保留您的解决方案,直到 angular 团队创造出更好的解决方案。

此致。

我有一个解决方法来获取当前路线的 URL 路段:

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot,
  ): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    const currentUrlFragments = route.pathFromRoot.flatMap((s) => s?.url ?? []).map((s) => s.path);
    return this.router.createUrlTree([...currentUrlFragments, '../']);
  }
}

还有一种解决方法是从 Router 中获取 url,就像这样 this.router.getCurrentNavigation()?.extractedUrl.toString()

完整示例如下:


@Injectable({
  providedIn: 'root',
})
export class MyGuard implements CanActivate, CanLoad {
  constructor(private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.redirect();
  }

  canLoad(
    route: Route,
    segments: UrlSegment[]
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.redirect();
  }

  private redirect() {
    let url = this.router.getCurrentNavigation()?.extractedUrl.toString() || '/';
    return this.router.createUrlTree([url, 'other', 'relative','path']);
  }
}

用上面的守卫保护像 hello/:name 这样的路径会导致导航到 hello/:name/other/relative/path,例如hello/world/other/relative/path.