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

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">&times;</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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:13