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
相关产品推荐
相关产品推荐

