Angular 5 & .NET Core 2.0:router.navigate跳转后页面冻结求助
Angular 5跳转后页面冻结问题解决方案
看起来你的问题是Bootstrap原生模态框和Angular路由不同步导致的页面冻结。虽然路由已经成功跳转到首页,但Bootstrap模态框的遮罩层(.modal-backdrop)没有被正确移除,同时body上的modal-open类也没清除——这就导致页面被遮罩层完全覆盖,看起来像是冻结了,但实际上首页已经正常加载完成了。
问题根源分析
你使用的是原生Bootstrap模态框(通过data-toggle、data-target触发),这类模态框基于DOM/jQuery操作,和Angular的组件生命周期没有绑定。当你调用router.navigate跳转路由后,Angular只会更新组件视图,但不会自动清理Bootstrap模态框留下的DOM状态(遮罩层、body的滚动锁定类),最终导致遮罩层挡住了所有交互。
从你提供的Chrome控制台和网络面板截图来看:
- 控制台没有报错,说明路由跳转逻辑本身没问题
- 网络请求显示删除接口成功返回,说明服务端操作也正常
所以问题的核心就是模态框的DOM残留。
解决方案1:手动清理模态框DOM(快速修复)
在跳转路由前,手动关闭模态框并清理相关DOM元素,修改你的logicAfterSettleDelete方法:
private logicAfterSettleDelete() { console.log(`Settle with id: ${this.settle.id} deleted!`); // 1. 关闭目标模态框 const modalElement = document.getElementById('deleteModalCenter'); if (modalElement) { // 移除Bootstrap模态框的显示类 modalElement.classList.remove('show'); modalElement.setAttribute('aria-hidden', 'true'); modalElement.style.display = 'none'; } // 2. 移除遮罩层 const backdropElement = document.querySelector('.modal-backdrop'); if (backdropElement) { backdropElement.remove(); } // 3. 恢复body的正常状态(解除滚动锁定) document.body.classList.remove('modal-open'); document.body.style.paddingRight = ''; // 清除Bootstrap添加的右侧padding // 最后执行路由跳转 this.router.navigate(['']); }
如果你的项目中已经引入了jQuery,也可以用Bootstrap官方的模态框关闭方法替代手动DOM操作:
// 替换上面的步骤1 $(modalElement).modal('hide');
解决方案2:使用Angular封装的Bootstrap组件(推荐)
原生Bootstrap和Angular的结合总会有这类DOM不同步的问题,更优雅的长期方案是使用ng-bootstrap——这是专门为Angular打造的Bootstrap组件库,模态框的状态完全由Angular的组件和服务管理,不会出现残留DOM的问题。
步骤1:安装依赖
npm install @ng-bootstrap/ng-bootstrap
步骤2:在AppModule中引入
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ imports: [ // ...其他导入 NgbModule ] }) export class AppModule { }
步骤3:重构模态框代码
修改模板为ng-bootstrap格式:
<!-- 触发按钮 --> <button type="button" class="btn btn-danger" (click)="openDeleteModal(deleteModalContent)"> Delete settle </button> <!-- 模态框模板 --> <ng-template #deleteModalContent let-modal> <div class="modal-header"> <h5 class="modal-title">Permanently delete settle "{{ settle.name }}"</h5> <button type="button" class="close" aria-label="Close" (click)="modal.dismiss('取消')"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> Are you sure you want to delete this kitty and all its data? </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" (click)="modal.close('关闭')">Close</button> <button type="button" class="btn btn-primary" (click)="confirmDelete(modal)">Delete</button> </div> </ng-template>
修改组件逻辑:
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; // 构造函数注入NgbModal服务 constructor( private modalService: NgbModal, private settleService: SettleService, private router: Router ) {} // 打开模态框 openDeleteModal(content: any) { this.modalService.open(content, { centered: true }); } // 确认删除逻辑 confirmDelete(modal: any): void { this.settleService .deleteSettle(this.settle.id) .subscribe(() => { modal.close('删除成功'); // 先关闭模态框 this.logicAfterSettleDelete(); }); } private logicAfterSettleDelete() { console.log(`Settle with id: ${this.settle.id} deleted!`); this.router.navigate(['']); // 现在跳转后页面不会冻结了 }
内容的提问来源于stack exchange,提问作者tzm
相关产品推荐
相关产品推荐

