AngularJs全選與單選相互控制的兩種方法
阿新 • • 發佈:2019-01-08
全選功能相信大家都遇到過,如果全選只是簡單的全部選中,全部取消勾選,無疑是一個很簡單的功能,但是在相互控制的情況下有些問題就可能考慮不周。這裡的相互控制是指:全選複選框控制列表所有項的全部選中和反全選,一項一項勾選列表項至每一項都勾選時,全選複選框狀態也被選中,列表項其中一個取消勾選,全選狀態取消選中。
方法一: $watch監聽
<div style="width: 800px; margin: 200px auto 0;">
<p>
<label>
<input type="checkbox" ng-model ="all">全選
</label>
</p>
<label class="margin-right-20" ng-repeat="item in list">
<input type="checkbox" ng-model="item.selectedStatus">{{item.name}}{{$index}}
</label>
</div>
// 監聽全選
$scope.$watch("all", function (n, o) {
if (n) {
// 全選
$scope.list.forEach(function (value) {
value.selectedStatus = true;
});
} else {
// 判斷是反全選還是列表項中有某些項沒選造成全選複選框為false
var midStatus = true;
$scope.list.forEach(function (value) {
midStatus = midStatus && value.selectedStatus;
});
// 如果列表項全是true,那麼反選
if (midStatus) {
$scope.list.forEach(function (value) {
value.selectedStatus = false;
});
}
}
});
// 監聽列表 全選的選中狀態根據列表項的 && 值確定
$scope.$watch("list", function (n, o) {
var midStatus = true;
$scope.list.forEach(function (value) {
midStatus = midStatus && value.selectedStatus;
});
$scope.all = midStatus;
}, true)
坑:在列表初始化時,如果預設列表是全部選中,由於相互監聽,會導致初始化全部選中實際操作是反全選。
解決方案: 在初始化過程中先不去執行監聽全選,等初始化之後再去執行監聽全選
$scope.list.forEach(function (value, index) {
value.selectedStatus = true;
value.name = "列表項";
if (index == $scope.list.length - 1) {
$timeout(function () {
$scope.$watch("all", function (n, o) {
if (n) {
$scope.list.forEach(function (value) {
value.selectedStatus = true;
});
} else {
var midStatus = true;
$scope.list.forEach(function (value) {
midStatus = midStatus && value.selectedStatus;
});
if (midStatus) {
$scope.list.forEach(function (value) {
value.selectedStatus = false;
});
}
}
});
}, 100)
}
});
方法二:ng-change
<div style="width: 800px; margin: 200px auto 0;">
<p>
<label>
<input type="checkbox" ng-model="all" ng-change="allSelect()">全選
</label>
</p>
<label class="margin-right-20" ng-repeat="item in list">
<input type="checkbox" ng-model="item.selectedStatus" ng-change="listItemSelect()">{{item.name}}{{$index}}
</label>
</div>
$scope.allSelect = function () {
if ($scope.all) {
$scope.list.forEach(function (value) {
value.selectedStatus = true;
});
} else {
var midStatus = true;
$scope.list.forEach(function (value) {
midStatus = midStatus && value.selectedStatus;
});
if (midStatus) {
$scope.list.forEach(function (value) {
value.selectedStatus = false;
});
}
}
};
$scope.listItemSelect = function () {
var midStatus = true;
$scope.list.forEach(function (value) {
midStatus = midStatus && value.selectedStatus;
});
$scope.all = midStatus;
}
坑:由於是 ng-change
指令,在初始化過程中並不會觸發函式,因此無法做到聯動,在初始化時需要去調 $scope.listItemSelect()
;