Angular-ngtable聯動全選

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

相關文章
相關標籤/搜索