Angular组件不使用ng-bootstrap打开Bootstrap Modal报错及方案问询
我正尝试在Angular组件中打开Bootstrap Modal,且不使用ng-bootstrap(项目尚未升级到Angular 14)。当前使用Bootstrap 4.6,已通过npm分别安装jquery、bootstrap、@popperjs/core,并在angular.json中配置了对应的styles和scripts。
组件HTML中定义了Modal元素:
<div class="modal fade" id="Modal" #Modal tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <!-- 模态框内容 --> </div>
在组件.ts的事件中调用$('#Modal').modal('show')时,出现异常:
core.mjs:7635 ERROR TypeError:.modal is not a function
请问如何解决该异常并正确打开模态框?是否存在不使用jquery、直接用@ViewChild实现的方式?
一、修复jQuery调用异常
.modal is not a function大多是jQuery和Bootstrap的加载顺序或全局引用问题,按以下步骤处理:
确认scripts加载顺序
Bootstrap依赖jQuery和Popper.js,必须保证加载顺序为:jquery→@popperjs/core→bootstrap,angular.json示例配置:"scripts": [ "node_modules/jquery/dist/jquery.min.js", "node_modules/@popperjs/core/dist/umd/popper.min.js", "node_modules/bootstrap/dist/js/bootstrap.min.js" ]在组件中声明全局jQuery变量
Angular默认不识别全局的$或jQuery,在组件顶部添加声明:declare var $: any;之后再调用
$('#Modal').modal('show')就能正常生效。验证jQuery加载状态
可以在ngAfterViewInit钩子中打印typeof $,如果输出function说明加载正常,否则检查文件路径是否正确,或是否存在重复加载的情况。
二、不使用jQuery,用@ViewChild+原生JS实现
Bootstrap 4的模态框支持原生JS实例化,完全不需要依赖jQuery:
通过@ViewChild获取模态框元素并实例化
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; import { Modal } from 'bootstrap'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html', styleUrls: ['./your-component.component.css'] }) export class YourComponentComponent implements AfterViewInit { @ViewChild('Modal') modalElement!: ElementRef; private modalInstance?: Modal; ngAfterViewInit(): void { // 初始化模态框实例 this.modalInstance = new Modal(this.modalElement.nativeElement); } // 打开模态框的方法 openModal(): void { this.modalInstance?.show(); } // 关闭模态框的方法 closeModal(): void { this.modalInstance?.hide(); } }调用方法触发模态框
在组件的事件(比如按钮点击)中调用openModal()即可:<button (click)="openModal()">打开模态框</button> <div class="modal fade" #Modal tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">模态框标题</h5> <button type="button" class="close" (click)="closeModal()" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> 模态框内容 </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" (click)="closeModal()">关闭</button> <button type="button" class="btn btn-primary">保存更改</button> </div> </div> </div> </div>
这种方式只需要保证Bootstrap的JS文件已在angular.json中加载即可,完全脱离jQuery依赖。
内容的提问来源于stack exchange,提问作者pokeRex110

