以前於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性能的問題。