จะลบองค์ประกอบออกจากวัตถุภายใน ng-reeat ได้อย่างไร?

ฉันกำลังพยายามลบองค์ประกอบหลายอย่างออกจากวัตถุ แต่ฉันได้รับข้อผิดพลาด วัตถุนี้อยู่ภายใน ng-repeat

ข้อผิดพลาด: ไม่อนุญาตให้ทำซ้ำในตัวทำซ้ำ ใช้นิพจน์ 'ติดตามโดย' เพื่อระบุคีย์ที่ไม่ซ้ำ ตัวทำซ้ำ: ลูกใน parent.beneficiaries, คีย์ซ้ำ: ไม่ได้กำหนด: ไม่ได้กำหนด, ค่าซ้ำ: ไม่ได้กำหนด

ฉันสร้างสคริปต์ง่ายๆ บน 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="[email protected]" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script data-require="[email protected]" 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="[email protected]" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/thstyle.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>

แล้วฉันทำอะไรผิดล่ะ?


person fablexis    schedule 22.02.2016    source แหล่งที่มา
comment
beneficiaries เป็นอาร์เรย์ ดังนั้น child in vm.classification[parent].beneficiaries จึงไม่ถูกต้องตั้งแต่แรก ไม่ใช่ delete vm.classification[parent].beneficiaries[child] เช่นกัน   -  person a better oliver    schedule 22.02.2016
comment
โอเค รูปแบบที่ถูกต้องในการทำเช่นนั้นคืออะไร? ถ้าฉันเพิ่มรหัสนั้น track by $index ภายใน <h5 ng-repeat="child in parent.beneficiaries> มันก็ใช้งานได้   -  person fablexis    schedule 22.02.2016


คำตอบ (2)


การใช้ 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)
  );
}
person a better oliver    schedule 22.02.2016
comment
คำตอบที่ดี! ชัดเจนมาก! ขอบคุณ! มันทำงานได้ดีมาก! - person fablexis; 22.02.2016

ระบบขอให้คุณมีตัวระบุที่ไม่ซ้ำกันสำหรับแต่ละรายการใน parent.beneficiaries นี่คือหน้า Angular อยู่ หากไม่มีรหัสเฉพาะ คุณสามารถลอง track by $index หรืออะไรทำนองนั้น แต่คุณควรใช้สิ่งนี้:

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

person tenor528    schedule 22.02.2016
comment
ด้วย ‹h5 ng-repeat=child ใน parent.beneficiaries ติดตามโดย child.idE› มันไม่ทำงาน :( - person fablexis; 22.02.2016
comment
ใช้งานได้หากใช้ track by $index! ขอบคุณ แต่ฉันมีคำถามอื่น จะลบรายการที่ถูกลบได้อย่างไร - person fablexis; 22.02.2016