为什么splice不删除angular.forEach中的所有项目?

时间:2015-01-07 16:19:24

标签: angularjs

在下面的代码中,当我点击“删除所有过期”按钮时,为什么它只删除status =过期的4个客户对象中的3个?

<html ng-app="mainModule">
    <head>
        <script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
        <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
    </head>    
    <body ng-controller="mainController" style="padding: 20px 0">

        <div class="col-lg-4">
            <table class="table-striped table-bordered table table-hover">
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Status</th>
                </tr>
                <tr ng-repeat="customer in customers| orderBy: 'lastName'">
                    <td>{{customer.firstName}}</td>
                    <td>{{customer.lastName}}</td>
                    <td ng-click="switchStatus(customer)" ng-class="{'text-danger': customer.status == 'expired'}" class="prohibitSelectionClickable">{{customer.status}}</td>
                </tr>
            </table>
            <button ng-click="deleteAllExpired()">Delete all expired</button>
        </div>

        <script>
                    var mainModule = angular.module('mainModule', []);
                            function mainController($scope) {

                                $scope.customers = [
                                    {id: 1, status: 'expired', firstName: 'Joe', lastName: 'Thompson'},
                                    {id: 2, status: 'expired', firstName: 'Hank', lastName: 'Howards'},
                                    {id: 3, status: 'expired', firstName: 'Clara', lastName: 'Okanda'},
                                    {id: 4, status: 'active', firstName: 'Thomas', lastName: 'Dedans'},
                                    {id: 5, status: 'expired', firstName: 'Zoe', lastName: 'Frappe'}
                                ];

                                $scope.deleteAllExpired = function () {
                                    angular.forEach($scope.customers, function (customer, index) {
                                        if (customer.status == 'expired') {
                                            $scope.customers.splice(index, 1);
                                        }
                                    });
                                };

                            }
        </script>
    </body>
</html>

2 个答案:

答案 0 :(得分:2)

这是因为您迭代的数组在迭代期间发生了更改(由于删除),并且不会遍历所有项目。将方法更改为:

$scope.deleteAllExpired = function () {

    var i = $scope.customers.length;

    while (i--) {
        var customer = $scope.customers[i];

        if (customer.status == 'expired') {
            $scope.customers.splice(i, 1);
        }
    }   
};

答案 1 :(得分:2)

很可能是因为splice() 变异数组,angular.forEach()使用无效索引。更好的实施IMO:

$scope.deleteAllExpired = function () {
    var newCustomers = [];
    angular.forEach($scope.customers, function (customer) {
        if (customer.status !== 'expired') {
            newCustomers.push(customer);
        }
    });
    $scope.customers = newCustomers;
};

你甚至可以获得性能提升,而不是那么多的突变(尽管对小型数据集来说可能是微不足道的。)