以前于Angular第三方插件ngTable的官网demo上看到的例子,但苦于demo中联动全选为选中全部,项目中并不适用,所以作了下小小的修改,修改目的只是为实现其功能,方法不敢苟同,如有更加简便的方法对此进行修改,请大方提出指正,本人不胜感激!javascript
好了,废话很少说,先上官网demo,说明其中缺陷。http://ng-table.com/#/formatting/demo-header-cell-fullhtml
如demo中所示,官网给的例子中点击全选时,全选为选中全部选项(即图中3页数据全被选中),而并非选中当前页面选项。java
以常理来讲这并不符合正常逻辑,容易给用户形成误解(如点击全选删除数据时只想删除当前页,但却删除所有数据)。git
所以作如下修改:为还原demo的样子,请容许我用bootstrap先简单作一个静态页面出来:github
html:json
<body> <div ng-app="myApp" class="container-fluid"> <script type="text/ng-template" id="headerCheckbox.html"> <input type="checkbox" ng-model="demo.checkboxes.checked" class="select-all" value="" /> </script> <div class="row"> <div class="col-md-6" ng-controller="index as demo"> <h3>ngTable</h3> <table ng-table="demo.tableParams" class="table table-condensed table-bordered table-striped"> <colgroup> <col width="5%"/> <col width="55%"/> <col width="20%"/> <col width="20%"/> </colgroup> <tr ng-repeat="row in $data"> <td header="'headerCheckbox.html'"><input type="checkbox" ng-model="demo.checkboxes.items[row.id]" /></td> <td title="'Name'">{{row.name}}</td> <td title="'Age'">{{row.age}}</td> <td title="'Money'">{{row.money}}</td> </tr> </table> </div> </div> </div> </body> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript" src="ng-table.js"></script>
而后是js中的修改。bootstrap
js代码:app
var App = angular.module("myApp", ["ngTable"]); App.controller("index", ['$scope', '$rootScope', 'NgTableParams', function($scope, $rootScope, NgTableParams) { /* * current: 列表当前页 * current_count: 列表当前页显示条数 * self.checkboxes.checked: 全选 * self.checkboxes.items: 当前选中个数用json形式保存 * simpleList: 表格数据 * */ $rootScope.current = 1; $rootScope.current_count = 5; var self = this, simpleList = [ {"id": 1, "name": "Nissim", "age": 41, "money": 454}, {"id": 2, "name": "Mariko", "age": 10, "money": -100}, {"id": 3, "name": "Mark", "age": 39, "money": 291}, {"id": 4, "name": "Allen", "age": 85, "money": 871}, {"id": 5, "name": "Dustin", "age": 10, "money": 378}, {"id": 6, "name": "Macon", "age": 9, "money": 128}, {"id": 7, "name": "Ezra", "age": 78, "money": 11}, {"id": 8, "name": "Fiona", "age": 87, "money": 285}, {"id": 9, "name": "Ira", "age": 7, "money": 816}, {"id": 10, "name": "Barbara", "age": 46, "money": 44}, {"id": 11, "name": "Lydia", "age": 56, "money": 494}, {"id": 12, "name": "Carlos", "age": 80, "money": 193} ]; self.checkboxes = { checked: false, items: {} }; self.tableParams = new NgTableParams( {count: 5}, {counts: [5, 10, 15], dataset: simpleList} ); // watch 全选 $scope.$watch(function() { return self.checkboxes.checked; }, function(value) { var total = ($rootScope.current_count * $rootScope.current > simpleList.length) ? simpleList.length : ($rootScope.current_count * $rootScope.current); angular.forEach(simpleList, function(data, index, array) { if (index >= ($rootScope.current - 1) * $rootScope.current_count && index < total) { self.checkboxes.items[array[index].id] = value; } }); }); // watch checkboxes.items $scope.$watch(function() { return self.checkboxes.items; }, function(values) { /** * checked: 选中个数 * unchecked:未选中个数 * total: 当前页总个数 * length: 当前页范围 */ var checked = 0, unchecked = 0, total = ($rootScope.current_count * $rootScope.current > simpleList.length) ? simpleList.length - ($rootScope.current - 1) * $rootScope.current_count : $rootScope.current_count, length = ($rootScope.current_count * $rootScope.current > simpleList.length) ? simpleList.length : ($rootScope.current_count * $rootScope.current); angular.forEach(simpleList, function(data, index, array) { if (index >= ($rootScope.current - 1) * $rootScope.current_count && index < length) { checked += (self.checkboxes.items[array[index].id]) || 0; unchecked += (!self.checkboxes.items[array[index].id]) || 0; } }); if ((unchecked == 0) || (checked == 0)) { self.checkboxes.checked = (checked == total); } // grayed checkbox angular.element(document.getElementsByClassName("select-all")).prop("indeterminate", (checked != 0 && unchecked != 0)); }, true); // watch 分页 $scope.$watch(function() { return $rootScope.current; }, function(newValue, oldValue) { if (newValue != oldValue) { self.checkboxes.checked = false; self.checkboxes.items = {}; } }); // watch 当前页显示条数 $scope.$watch(function() { return $rootScope.current_count; }, function(newValue, oldValue) { if (newValue != oldValue) { self.checkboxes.checked = false; self.checkboxes.items = {}; } }); } ]);
如js代码中所示,多出了两个$rootScope值(current和current_count),所以在原有的ng-table.js中也需作相应修改:函数
在ng-table.js插件中541行的函数中,加入$rootScope。性能
并在该函数的
(1)this.page处添加$rootScope.current = params.page;以记录选中当前页;
(2)this.count处添加$rootScope.current_count = params.count;以记录当前显示条数;
至此修改完成,在点击全选时效果为选中当前页面选项,而且在修改显示条数的状况下进行选中清空处理。
demo地址:https://wang-sai.github.io/datalibrary/angular/ngtable-checkboxall.html
最后要说明的是,这个方法虽然能够完成相关功能,怎么说呢,彻底是为实现功能添加的代码。
首先是改动了ngtable的源码,其次demo中的数据量并不大,在实际项目中数据量确定是比较大的,少则几十页,多则上百页,有可能会出现$watch性能的问题。