如何从ng-repeat中的对象中删除元素?

时间:2016-02-22 14:35:18

标签: javascript angularjs loops object

我正在尝试从对象中删除多个元素但我收到错误,此对象位于ng-repeat内。

错误不允许在转发器中重复。使用'track by'表达式指定唯一键。 Repeater:parent.beneficiaries中的child,Duplicate key:undefined:undefined,Duplicate value:undefined

我在plukr上制作了一个简单的脚本:https://plnkr.co/edit/W2C9ML4dEgJzqj6JeqWC?p=preview

我的控制器:

angular
  .module("myApp", [])
  .controller("myCtrl", myCtrl);

  function myCtrl(){
    var vm = this;

    vm.classification = [
        {
          "name": "Favoritos",
          "beneficiaries":[
            {
              "idE": "1",
              "type": "Beneficiarios",
              "name": "Alexander Bueno",
              "selected": false
            },
            {
              "idE": "2",
              "type": "Beneficiarios",
              "name": "Lorena Torrealba",
              "selected": false
            },
            {
              "idE": "3",
              "type": "Beneficiarios",
              "name": "Fabián Pernía",
              "selected": false
            }
          ]
        },
        {
          "name": "Mis cuentas",
          "beneficiaries":[
            {
              "idE": "8",
              "type": "Cuentas",
              "name": "Corriente ...1234",
              "selected": false
            },
            {
              "idE": "9",
              "type": "Cuentas",
              "name": "Corriente ...9854",
              "selected": false
            },
            {
              "idE": "10",
              "type": "Cuentas",
              "name": "Ahorro ...9921",
              "selected": false
            }
          ]
        },
        {
          "name": "Terceros",
          "beneficiaries":[
            {
              "idE": "4",
              "type": "Beneficiarios",
              "name": "Alexander Ramírez",
              "selected": false
            },
            {
              "idE": "5",
              "type": "Beneficiarios",
              "name": "Vicente Delgado",
              "selected": false
            },
            {
              "idE": "6",
              "type": "Beneficiarios",
              "name": "Alexis Rodríguez",
              "selected": false
            },
            {
              "idE": "7",
              "type": "Beneficiarios",
              "name": "Ignacio Bueno",
              "selected": false
            }
          ]
        },
        {
          "name": "Tarjetas",
          "beneficiaries":[
            {
              "idE": "11",
              "name": "Visa ...6987",
              "selected": false
            },
            {
              "idE": "12",
              "name": "MasterCard ...7841",
              "selected": false
            }
          ]
        },
        {
          "name": "Servicios",
          "beneficiaries":[
            {
              "idE": "13",
              "name": "Electricidad de Caracas",
              "selected": false
            },
            {
              "idE": "14",
              "name": "C.A.N.T.V",
              "selected": false
            }
          ]
        }
      ];

    //function to delete elements
    vm.deleteElements = function(){
      for(var parent in vm.classification){
        for(var child in vm.classification[parent].beneficiaries){
          //if an element is selected then it will be deleted
          if(vm.classification[parent].beneficiaries[child].selected)
            //this fails if there are more than one element
            delete vm.classification[parent].beneficiaries[child]
        }
      }
    }
  }

我的观点:

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script data-require="angular.js@1.3.14" data-semver="1.3.14" src="https://code.angularjs.org/1.3.14/angular.js"></script>
    <script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script data-require="bootstrap@3.3.6" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="myCtrl as ctrl">
    <h1>Elements</h1>
    <a class="btn btn-danger" ng-click="ctrl.deleteElements();">Delete selected elements</a>

    <div class="well" ng-repeat="parent in ctrl.classification">
      <h3>{{parent.name}}</h3>
      <h5 ng-repeat="child in parent.beneficiaries">
        <input type="checkbox" ng-model="child.selected">{{child.name}}
      </h5>
    </div>

  </body>

</html>

那么,我做错了什么?

2 个答案:

答案 0 :(得分:1)

它要求您为parent.beneficiaries中的每个项目设置一些唯一标识符。 Here is the Angular page on it。如果没有唯一ID,您可以尝试track by $index或类似的东西。但你应该可以使用它:

<h5 ng-repeat="child in parent.beneficiaries track by child.idE">

答案 1 :(得分:1)

使用for ... in循环遍历数组是不正确的,因为它不仅仅考虑数组的元素。也没有用delete删除数组的元素。这不会改变数组的大小。

一个相当简单的解决方案是过滤数组:

vm.deleteElements = function(){
  vm.classification.forEach(function (classification) {
    classification.beneficiaries = classification.beneficiaries.filter(function(beneficiary) {
      return !beneficiary.selected;
    });
  });
}

或者,如果浏览器支持ES6:

vm.deleteElements = function(){
  vm.classification.forEach( classification =>
    classification.beneficiaries = classification.beneficiaries.filter(beneficiary => !beneficiary.selected)
  );
}