简体   繁体   English

AngularJS ngRepeat元素删除

[英]AngularJS ngRepeat element removal

There are quite a few questions on how to implement item removal inside ngRepeat directive, and as I figured out, it comes down to using ngClick and triggering some remove function passing it item's $index . 关于如何在ngRepeat指令中实现项目删除有很多问题,正如我所知,它归结为使用ngClick并触发一些删除函数传递项目的$ index

However, I couldn't find anywhere an example where I have multiple ngRepeats: 但是,我找不到任何有多个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>

For this, I would need to create $scope.removePhone and $scope.removeEmail which would be called using ngClick on Remove anchor . 为此,我需要创建$ scope.removePhone$ scope.removeEmail ,这将使用ngClick on Remove anchor来调用。 But I'm looking for a more generic solution. 但我正在寻找更通用的解决方案。 Especially since I have many pages with many ngRepeats . 特别是因为我有很多页面有很多ngRepeats

I was thinking about writing a directive which would be placed on Remove anchor and would do something like this: 我正在考虑编写一个可以放在Remove锚点上的指令,并且会做类似这样的事情:

  1. Find ngRepeat among parent elements. 在父元素中查找ngRepeat
  2. Read what it's iterating over ('user.emails' in first case, 'user.phones' in second) 阅读它的迭代内容(第一种情况为'user.emails',第二种情况为'user.phones')
  3. Remove $index element from THAT model. THAT模型中删除$ index元素。

So the markup would look something like this: 所以标记看起来像这样:

<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>

Is what I'm looking for possible to achieve and what would be the preferred way to do this? 我正在寻找可能实现的目标,以及这样做的首选方式是什么?

Current hacky solution 目前的hacky解决方案

Here is how I do it currently. 这是我目前的工作方式。 It's hacky and ugly but gets the job done until I figure out a prettier way. 这很丑陋而且很丑陋,但直到我找到一个更漂亮的方式才能完成工作。

  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);
    };
  });

And in DOM: 在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>

You could create a generic remove method that would take in the array and the item to remove. 您可以创建一个通用的删除方法,该方法将接受数组和要删除的项。

<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);
}

No JS 没有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>

A very simple and convenient way that works cross-browser is to use the 'remove' utility method from the library lodash. 跨浏览器工作的一种非常简单方便的方法是使用库lodash中的“remove”实用程序方法。

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

In your controller you declare then 然后在你的控制器中声明

//inject lodash dependency

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

You may of course use indexes if you like. 如果您愿意,您当然可以使用索引。 See https://lodash.com/docs#remove 请参阅https://lodash.com/docs#remove

If you have used ng-repeat on an object instead of an array, do the following. 如果您在对象而不是数组上使用了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];
}

or the more terse 或者更简洁

<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>

presumes that the objects look like this 假设物体看起来像这样

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM