AngularJS与DataTable中带ng-change的Checkbox无法触发函数求助
解决AngularJS + DataTables中DTColumnBuilder绑定ng-change不触发的问题
我懂你遇到的这个头疼问题——用DTColumnBuilder给列头加了带ng-change="checkedAll()"的复选框,结果点击完全没反应,连最基础的alert都弹不出来对吧?这本质上是因为DataTables动态生成的DOM元素没经过AngularJS的编译流程,导致指令和作用域的绑定完全失效了。
下面给你几个靠谱的解决方案,你可以按需选择:
方案1:用DataTables的initComplete回调手动编译DOM
当DataTables初始化完成后,手动调用Angular的$compile服务,把列头的复选框纳入Angular的作用域管理:
// 先配置dtOptions,添加初始化完成后的回调 vm.dtOptions = DTOptionsBuilder.newOptions() .withOption('initComplete', function(settings, json) { // 获取列头的复选框元素 var selectAllCheckbox = angular.element('#example-select-all'); // 编译元素并绑定到当前作用域 $compile(selectAllCheckbox)($scope); }); // 你的列定义保持不变 vm.dtColumns.push(DTColumnBuilder.newColumn('id') .withTitle('<input name="select_all" value="1" id="example-select-all" type="checkbox" ng-change="checkedAll()" />') .renderWith(actionHtml) .withOption('orderable', false)); // 作用域函数不变 $scope.checkedAll = function () { alert('全选复选框被触发啦!'); }
方案2:改用原生事件委托(无需依赖Angular编译)
如果不想用$compile,可以通过事件委托直接监听复选框的change事件,手动触发作用域内的函数:
// 在控制器初始化时添加事件监听 angular.element(document).on('change', '#example-select-all', function() { // 用$apply告诉Angular更新作用域状态 $scope.$apply(function() { $scope.checkedAll(); }); }); // 列定义里可以去掉ng-change(留着也不影响) vm.dtColumns.push(DTColumnBuilder.newColumn('id') .withTitle('<input name="select_all" value="1" id="example-select-all" type="checkbox" />') .renderWith(actionHtml) .withOption('orderable', false)); $scope.checkedAll = function () { alert('全选复选框被触发啦!'); }
方案3:检查作用域绑定是否匹配(针对controllerAs语法)
如果你用了controllerAs语法(比如用vm作为控制器别名),要确保函数挂在控制器实例上,同时模板里的指令也要对应修改:
// 把函数挂在vm上,而非$scope vm.checkedAll = function () { alert('全选复选框被触发啦!'); } // 列定义里的ng-change要对应改为vm.checkedAll() vm.dtColumns.push(DTColumnBuilder.newColumn('id') .withTitle('<input name="select_all" value="1" id="example-select-all" type="checkbox" ng-change="vm.checkedAll()" />') .renderWith(actionHtml) .withOption('orderable', false)); // 记得在initComplete编译时,用控制器的作用域(如果用了controllerAs) vm.dtOptions = DTOptionsBuilder.newOptions() .withOption('initComplete', function(settings, json) { var selectAllCheckbox = angular.element('#example-select-all'); $compile(selectAllCheckbox)(vm); // 这里用vm替代$scope });
问题根源说明
DataTables是jQuery生态的插件,它动态生成的DOM元素不会自动经过AngularJS的编译流程,所以Angular无法识别其中的ng-change指令,自然不会绑定到对应的作用域函数。上面的方案要么手动触发编译,要么绕开Angular指令直接用事件监听,都能解决这个绑定失效的问题。
内容的提问来源于stack exchange,提问作者hetal gohel
相关产品推荐
相关产品推荐

