【问题标题】:AngularJS ngRepeat element removalAngularJS ngRepeat 元素删除
【发布时间】:2013-08-17 14:10:59
【问题描述】:

关于如何在 ngRepeat 指令中实现项目删除有很多问题,据我所知,它归结为使用 ngClick 并触发一些删除函数,传递它的项目的 $索引

但是,我在任何地方都找不到我有多个 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

我正在考虑编写一个指令,该指令将放置在 Remove anchor 上,并会执行以下操作:

  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>

我正在寻找的目标是否可能实现?最好的方法是什么?

当前的 hacky 解决方案

这是我目前的做法。它既丑陋又丑陋,但在我找到更漂亮的方法之前可以完成工作。

  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>

【问题讨论】:

  • “无 JS”是最好的答案。 (如果你只看一个投票最多的人)

标签: javascript angularjs angularjs-directive angularjs-scope


【解决方案1】:

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

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

【讨论】:

  • 虽然这行得通并且确实让我想到了,但它仍然需要我重复自己(据我所知,这在编程中是一件坏事:-)):我已经指定我正在迭代邮件,我想“跳过”我必须重新定义的部分(方法调用中的“电子邮件”参数)。我想留下 remove(email)
  • 不重复自己是理想的,但保持简单也很重要。
  • 你不是在重复自己,你是在不同的位置用不同的参数多次调用一个函数。一天结束时,您需要构建应用程序,因此应该务实;)
  • 也许题外话,但是当对象不是数组时,如何从 ng-repeat 中删除它?不知道如何传入正确的对象以从视图中删除。
  • 有人在使用这个时注意到延迟了吗?似乎需要几秒钟才能从对象/数组中删除项目。
【解决方案2】:

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

【讨论】:

  • 最简单,最简单,最好的角度使用
  • 出色的工作,这正是我想要的。简洁无垃圾。
  • 嗯...有 javascript。我认为您的意思是“没有 external JS”
【解决方案3】:
<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>

【讨论】:

  • 这可能是最好的答案。如果您要删除没有验证的项目,没有软删除(从列表中删除但保留在内存中),这非常优雅。如果您想将“代码”排除在 html 声明之外,您始终可以将其包装为一种方法。
【解决方案4】:

一种非常简单方便的跨浏览器工作方式是使用库 lodash 中的“删除”实用程序方法。

<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

【讨论】:

  • 我知道这真的很老了,但值得一提的是,这个答案正在使用 lodash 的特定 ng-lodash 实现:github.com/rockabox/ng-lodash
【解决方案5】:

如果您在对象而不是数组上使用了 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', .... }  };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2013-01-10
    • 2015-01-25
    • 2015-05-23
    • 2015-12-14
    • 2013-12-02
    相关资源
    最近更新 更多