AngularJS集成select2报错element.select2 is not a function求助
问题原因和修改方案
- 脚本加载顺序错误:当前代码中AngularJS加载在jQuery之前,Angular默认会使用内置的jqLite而非完整jQuery对象,导致指令里的element没有被jQuery包装,无法调用select2方法。需要把jQuery的script标签放到所有Angular相关脚本的前面,调整后的加载顺序如下:
<!-- 先加载jQuery --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- 再加载Angular相关脚本 --> <script src="../../scripts/angular.min.js"></script> <script src="../../scripts/angular-route.min.js"></script> <!-- 最后加载依赖jQuery的组件 --> <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
- 模块定义错误:当前
var app = angular.module('TestApp');是尝试获取已存在的TestApp模块,而非创建新模块,会抛出模块不存在的报错。修改为带空依赖数组的创建模块写法:
var app = angular.module('TestApp', []);
- 样式引入属性缺失:HTML中select2的css引入标签缺少
rel="stylesheet"属性,会导致样式无法正常加载,修改为:
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
- 指令逻辑适配select2 4.x版本:当前使用的select2 4.0.0版本已不支持
element.select2("val", newVal)的赋值写法,同时原生setTimeout会导致Angular作用域同步异常,建议替换为Angular内置的$timeout,补充双向绑定同步和内存释放逻辑,修改后的指令代码如下:
app.directive('wbSelect2', function ($timeout) { return { restrict: 'A', require: 'ngModel', scope: { 'selectWidth': '@', 'ngModel': '=' }, link: function (scope, element, attrs, ngModelCtrl) { scope.selectWidth = scope.selectWidth || 200; // 等待ng-repeat渲染完option后再初始化select2 $timeout(function() { element.select2({ width: scope.selectWidth, }); // 下拉选中变更同步到ngModel element.on('change', function () { scope.$apply(function () { ngModelCtrl.$setViewValue(element.val()); }); }); }); // 监听ngModel变化,同步到select2 scope.$watch('ngModel', function (newVal) { if(newVal !== undefined) { element.val(newVal).trigger('change'); } }); // 组件销毁时释放select2实例,避免内存泄漏 scope.$on('$destroy', function() { element.select2('destroy'); }); } }; });
如果调整加载顺序后仍报错,可尝试手动用jQuery包装element,把所有element.select2替换为$(element).select2即可。
内容的提问来源于stack exchange,提问作者FaceLess No One
相关产品推荐
相关产品推荐

