AngularJS ngRepeat元素删除

AngularJS ngRepeat element removal

本文关键字:删除 元素 ngRepeat AngularJS      更新时间:2023-09-26

关于如何在ngRepeat指令中实现项删除,有很多问题,正如我所了解的,归根结底是使用ngClick并触发一些将项的$index传递给它的删除函数。

然而,我在任何地方都找不到有多个ngRepeats:的例子

<div ng-controller="MyController">
    <div ng-repeat="email in user.emails">
        {{ email }} <a href>Remove</a>
    </div>
    <div ng-repeat="phone in user.phones">
        {{ phone }} <a href>Remove</a>
    </div>
</div>

为此,我需要创建$scope.removePhone$scope.removeEmail,这将使用ngClick删除锚点上调用。但我正在寻找一个更通用的解决方案。特别是因为我有许多页面有许多ngRepeats

我正在考虑写一个指令,放在删除锚点上,然后做这样的事情:

  1. 在父元素中查找ngRepeat
  2. 阅读它的迭代内容(第一种情况下为"user.emails",第二种情况下则为"user.phones")
  3. THAT模型中删除$index元素

所以标记看起来像这样:

<div ng-controller="MyController">
    <div ng-repeat="email in user.emails">
        {{ email }} <a href remove-directive="$index">Remove</a>
    </div>
    <div ng-repeat="phone in user.phones">
        {{ phone }} <a href remove-directive="$index">Remove</a>
    </div>
</div>

我所寻找的是可能实现的吗?最好的方法是什么?

当前的破解解决方案

以下是我目前的做法。它既粗糙又丑陋,但在我找到更漂亮的方法之前,它会完成任务。

  myAppModule.controller('MyController', function ($scope, $parse, $routeParams, User) {
    $scope.user = User.get({id: $routeParams.id});
    $scope.remove = function ($index, $event) {
      // TODO: Find a way to make a directive that does this. This is ugly. And probably very wrong.
      var repeatExpr = $($event.currentTarget).closest('[ng-repeat]').attr('ng-repeat');
      var modelPath  = $parse(repeatExpr.split('in')[1].replace(/^'s+|'s+$/g, ''));
      $scope.$eval(modelPath).splice($index, 1);
    };
  });

在DOM中:

<div ng-repeat="email in user.email" class="control-group">
  <label class="control-label">
    {{ "Email Address"|_trans }}
  </label>
  <div class="controls">
    <input type="text" ng-model="email.address">
    <span class="help-inline"><a href ng-click="remove($index, $event)">{{ "Delete"|_trans }}</a></span>
  </div>
</div>

您可以创建一个通用的移除方法,该方法将接受数组和要移除的项。

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} <a ng-click="remove(emails, $index)">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} <a ng-click="remove(phones, $index)">Remove</a>
    </div>
</div>
$scope.remove = function(array, index){
    array.splice(index, 1);
}

无JS

<div ng-repeat="option in options" ng-init=options=[1,2,3,4,5]>
   <button ng-click="options.splice($index,1)">Remove me</button>      
</div>
<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails as datasource">{{ email }} 
        <a ng-click="datasource.splice($index,1)">Remove</a>
    </div>
    <div ng-repeat="phone in phones as datasource">{{ phone }} 
        <a ng-click="datasource.splice($index,1)">Remove</a>
    </div>
</div>

跨浏览器工作的一种非常简单方便的方法是使用库lodash中的"remove"实用程序方法。

<div ng-repeat="phone in phones">{{ phone }} 
  <a ng-click="removeItem(phones, phone)">Remove</a>
</div>

在您的控制器中,您声明然后

//inject lodash dependency
//declare method in scope
$scope.removeItem = function(list, item){
   lodash.remove(list,function(someItem) { return item === someItem});
}

如果你愿意,当然可以使用索引。看见https://lodash.com/docs#remove

如果您在对象而不是数组上使用了ng repeat,请执行以下操作。

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} 
      <a ng-click="remove(emails, email)">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} 
      <a ng-click="remove(phones, phone)">Remove</a>
    </div>
</div>
$scope.remove = function(objects, o){
    delete object[o.id];
}

或者更简洁的

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} 
      <a ng-click="delete emails[email.id]">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} 
      <a ng-click="delete phones[phone.id]">Remove</a>
    </div>
</div>

假设对象看起来像这个

var emails = {  '123' : { id : '123', .... }  };
var phones = {  '123' : { id : '123', .... }  };