【问题标题】:How to delete an element from an object inside a ng-repeat?如何从 ng-repeat 内的对象中删除元素?
【发布时间】:2016-06-04 00:54:05
【问题描述】:

我试图从一个对象中删除几个元素,但我收到了一个错误,这个对象在一个 ng-repeat 中。

错误不允许在转发器中重复。使用“track by”表达式指定唯一键。中继器: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="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>

那么,我做错了什么?

【问题讨论】:

  • beneficiaries 是一个数组,所以 child in vm.classification[parent].beneficiaries 不正确,首先。 delete vm.classification[parent].beneficiaries[child] 也不是。
  • 好的,这样做的正确形式是什么?如果我在 &lt;h5 ng-repeat="child in parent.beneficiaries&gt; 内添加代码 track by $index 它可以工作

标签: javascript angularjs loops object


【解决方案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)
  );
}

【讨论】:

  • 很好的答案!非常清楚!谢谢!效果很好!
【解决方案2】:

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

&lt;h5 ng-repeat="child in parent.beneficiaries track by child.idE"&gt;

【讨论】:

  • 它不起作用:(
  • 如果使用 track by $index 就可以了!谢谢,但我还有一个问题,如何删除已删除的条目?
猜你喜欢
  • 2015-11-29
  • 2017-01-15
  • 1970-01-01
  • 2017-12-03
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多