You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用router.navigate后如何确定新路由?路由守卫拦截场景

嘿,这个问题我之前帮不少开发者解决过——Angular的CanDeactivate守卫里确实没有直接的this.router.newRoute属性,但完全不用靠全局变量这种不太优雅的方式,有几个更合适的方案:

解决方案:在CanDeactivate守卫中获取目标路由
  • 方法1:通过Router.getCurrentNavigation()获取目标路由
    这是最直接的原生方式,当你调用this.router.navigate()时,Angular会生成一个当前导航对象,你可以在守卫里通过它拿到最终的目标路由信息:
import { CanDeactivate } from '@angular/router';
import { Router } from '@angular/router';
import { Injectable } from '@angular/core';

@Injectable()
export class MyDeactivateGuard implements CanDeactivate<MyComponent> {
  constructor(private router: Router) {}

  canDeactivate(component: MyComponent): boolean | Observable<boolean> {
    // 获取目标路由的完整URL字符串
    const targetUrl = this.router.getCurrentNavigation()?.finalUrl?.toString();
    if (targetUrl === '/myApp/userProfiles') {
      // 这里写你的拦截逻辑,比如确认弹窗
      return confirm(`确定要跳转到用户列表页吗?`);
    }
    return true;
  }
}

⚠️ 注意:getCurrentNavigation()仅在导航过程中有效,导航完成后会被重置为null,所以一定要在canDeactivate方法内调用它。

  • 方法2:通过导航状态传递目标标识
    如果你需要更灵活地传递目标路由的自定义信息,可以在调用navigate时附加状态参数,再在守卫里读取:
    首先,发起导航时:
this.router.navigate(["myApp/userProfiles"], {
  state: { targetPage: 'userProfiles' }
});

然后在守卫中获取状态:

canDeactivate(component: MyComponent): boolean | Observable<boolean> {
  const navigationState = this.router.getCurrentNavigation()?.extras.state;
  if (navigationState?.targetPage === 'userProfiles') {
    // 执行你的拦截逻辑
    return true;
  }
  return false;
}
  • 方法3:监听Router的NavigationStart事件
    你也可以在守卫里订阅路由的NavigationStart事件,实时捕获每次导航的目标URL。但要记得在守卫销毁时取消订阅,避免内存泄漏:
import { Subscription } from 'rxjs';
import { NavigationStart } from '@angular/router';
import { OnDestroy } from '@angular/core';

@Injectable()
export class MyDeactivateGuard implements CanDeactivate<MyComponent>, OnDestroy {
  private navigationSub: Subscription;
  private targetUrl: string | null = null;

  constructor(private router: Router) {
    this.navigationSub = this.router.events.subscribe(event => {
      if (event instanceof NavigationStart) {
        this.targetUrl = event.url;
      }
    });
  }

  canDeactivate(component: MyComponent): boolean | Observable<boolean> {
    if (this.targetUrl === '/myApp/userProfiles') {
      return confirm(`确认离开当前页面跳转到${this.targetUrl}吗?`);
    }
    return true;
  }

  ngOnDestroy() {
    this.navigationSub.unsubscribe();
  }
}

总结一下,优先用第一种方法,它是Angular官方提供的最简洁可靠的方式,不需要额外传递状态或订阅事件。

内容的提问来源于stack exchange,提问作者John Glabb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:57:22