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

Angular路由拦截时确认弹窗重复弹出问题及解决诉求

解决Angular路由拦截弹窗重复触发问题

问题根源

你的代码出现两次弹窗有两个核心原因:

  • 调用this.router.navigateByUrl(currentRoute.snapshot.url, { skipLocationChange: true })会再次触发NavigationStart事件,导致弹窗逻辑重复执行
  • 没有状态标记,无法阻止同一流程下的重复触发

修复方案

1. 新增状态标记防重复

添加布尔变量标记当前是否处于确认弹窗流程,避免重复进入弹窗逻辑。

2. 改用event.preventDefault()阻止默认导航

代替手动跳转当前路由的方式,直接调用路由事件的preventDefault()方法拦截默认导航,避免额外触发路由事件。

3. 规范路由事件监听并清理订阅

用subscribe监听路由事件(router.events是Observable,subscribe更符合RxJS规范),同时在组件销毁时取消订阅,防止内存泄漏。

修改后的完整代码

import { Component, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
  // 你的组件元数据
})
export class YourComponent implements OnDestroy {
  private routeSubscription: Subscription;
  private isConfirming = false; // 新增状态标记,控制弹窗触发时机

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private modalService: YourModalService // 确保注入你的弹窗服务
  ) {
    this.routeSubscription = this.router.events.subscribe((event) => {
      // 仅当未处于确认流程、有未保存内容、且是路由开始事件时执行
      if (event instanceof NavigationStart && !this.isConfirming && this.paContentId) {
        this.isConfirming = true;
        event.preventDefault(); // 阻止默认路由跳转

        const modalRef = this.modalService.open(ConfirmPopupComponent, { 
          centered: true,
          modalDialogClass: 'confirm-model custom-modal'
        });

        modalRef.componentInstance.displayValue = {
          title: 'Confirm',
          content: 'You have unsaved changes. System will clear all of these data if you switch to another screen. Do you want to proceed?'
        };

        modalRef.componentInstance.checkConfirm.subscribe((receivedCheck: boolean) => {
          this.isConfirming = false; // 确认完成后重置标记
          if (receivedCheck) {  
            this.paContentId = '';
            this.router.navigate([event.url]); // 用户确认后执行跳转
          }
          // 用户取消则不做操作,保持当前页面
        });
      }
    });
  }

  ngOnDestroy(): void {
    // 组件销毁时清理订阅,避免内存泄漏
    if (this.routeSubscription) {
      this.routeSubscription.unsubscribe();
    }
  }
}

关键修改说明

  • isConfirming变量:确保同一时间只有一个确认弹窗在处理,彻底避免重复触发
  • event.preventDefault():直接拦截默认路由行为,消除二次触发NavigationStart的源头
  • 移除多余的this.router.navigateByUrl调用:不再手动触发额外路由事件
  • 新增ngOnDestroy钩子:清理路由事件订阅,避免长期内存占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:03:28