1. 程式人生 > >AngularJs全選與單選相互控制的兩種方法

AngularJs全選與單選相互控制的兩種方法

全選功能相信大家都遇到過,如果全選只是簡單的全部選中,全部取消勾選,無疑是一個很簡單的功能,但是在相互控制的情況下有些問題就可能考慮不周。這裡的相互控制是指:全選複選框控制列表所有項的全部選中和反全選,一項一項勾選列表項至每一項都勾選時,全選複選框狀態也被選中,列表項其中一個取消勾選,全選狀態取消選中。

方法一: $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() ;