AngularJS DataTable中ng-click、ng-model异常问题求助
嘿,我来帮你搞定这两个DataTables的问题,咱们一步步拆解:
问题1:checkValue函数无法获取用户id,控制台输出undefined
原因分析
你用了DataTables的AngularJS模式(datatable="ng"),同时配置了dtOptions和dtColumns——这时候DataTables会自动接管表格内容的渲染,你写在<tbody>里的ng-repeat根本不会生效!所以ng-click="Ctrl.checkValue(user.id)"里的user变量根本不存在,自然输出undefined。
另外,你写的ng-true-value="{{user.id}}"也有语法问题,正确写法应该用单引号包裹值,让AngularJS识别为字符串,不过这是次要问题,核心还是ng-repeat没起作用。
解决方法
要在DataTables渲染的行里添加复选框和点击事件,得通过dtColumns定义自定义模板,结合renderWith函数来处理每一行的数据:
修改你的dtColumns配置,给第一列生成包含复选框的模板,同时把用户id正确传递到checkValue函数:
vm.dtColumns = [ DTColumnBuilder.newColumn(null).withTitle('') .renderWith(function(data, type, full) { // full是当前行的完整数据对象,包含id和name return '<input type="checkbox" id="user-' + full.id + '" ng-model="Ctrl.checkboxValue[' + full.id + ']" ng-click="Ctrl.checkValue(' + full.id + ')" ng-true-value="' + full.id + '" /><label for="user-' + full.id + '"></label>'; }), DTColumnBuilder.newColumn('name').withTitle('Name') .renderWith(function(data, type, full) { return '<a href="#">' + data + '</a>'; }) ];
这样DataTables渲染每一行时,会用当前行的full对象(也就是你的user数据)生成模板,full.id就能正确获取到用户id,传递给checkValue函数。
同时别忘了保留dtOptions里的createdRow配置,让AngularJS能解析模板里的指令:
.withOption('createdRow', function(row, data, dataIndex) { $compile(angular.element(row).contents())($scope); })
问题2:checkboxValue数组异常,同一时间只能选中一个
原因分析
还是因为原来的ng-repeat没生效,$index是undefined,所以ng-model="Ctrl.checkboxValue[$index]"实际上是把值存在了Ctrl.checkboxValue[undefined]这个位置——每次选中新的复选框都会覆盖这个位置的值,所以看起来只能选一个,数组里的键也变成了undefined。
解决方法
上面修改模板的时候,已经把ng-model改成了Ctrl.checkboxValue[' + full.id + '],这样每个复选框的model都会绑定到以用户id为键的位置,比如选中id=1的用户,就会存在checkboxValue[1] = '1',选中id=2的就是checkboxValue[2] = '2',多个复选框可以同时选中,数组结构也正常了。
另外,把checkboxValue初始化为对象会比数组更合适,毕竟用id作为键更符合场景:
vm.checkboxValue = {}; // 改成对象,替代原来的数组
最后,HTML里的<tbody>可以清空,因为DataTables会自动渲染内容:
<tbody></tbody>
修改后的完整脚本代码
angular.module('myApp', ['ngAnimate', 'ngSanitize', 'datatables', 'datatables.columnfilter']) .controller('appController', function($scope, $compile, DTOptionsBuilder, DTColumnBuilder){ $scope.userList = [ { id: '1', name: 'hello' }, { id: '2', name: 'hi' } ]; var vm = this; vm.dtOptions = DTOptionsBuilder.newOptions() .withPaginationType('full_numbers') .withOption('createdRow', function (row, data, dataIndex) { $compile(angular.element(row).contents())($scope); }) .withColumnFilter({ aoColumns: [{ }, { type: 'text', bRegex: true, bSmart: true }] }); vm.dtColumns = [ DTColumnBuilder.newColumn(null).withTitle('') .renderWith(function(data, type, full) { return '<input type="checkbox" id="user-' + full.id + '" ng-model="Ctrl.checkboxValue[' + full.id + ']" ng-click="Ctrl.checkValue(' + full.id + ')" ng-true-value="' + full.id + '" /><label for="user-' + full.id + '"></label>'; }), DTColumnBuilder.newColumn('name').withTitle('Name') .renderWith(function(data, type, full) { return '<a href="#">' + data + '</a>'; }) ]; vm.checkboxValue = {}; vm.checkValue = function(id){ console.log(id); // 现在能正常输出用户id了 } });
内容的提问来源于stack exchange,提问作者abhiox

