266

我正在尝试编写一个函数,使我能够在单击按钮时删除一个项目,但我认为我对该函数感到困惑 - 我使用$digest吗?

HTML & app.js:

<ul ng-repeat="bday in bdays">
  <li>
    <span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
    <form ng-show="editing" ng-submit="editing = false">
      <label>Name:</label>
      <input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
      <label>Date:</label>
      <input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
      <br/>
      <button class="btn" type="submit">Save</button>
      <a class="btn" ng-click="remove()">Delete</a>
    </form>
  </li>
</ul>

$scope.remove = function(){
  $scope.newBirthday = $scope.$digest();
};
4

12 回答 12

564

要删除项目,您需要将其从数组中删除,并且可以将bday项目传递给标记中的删除函数。然后在控制器中查找项目的索引并从数组中删除

<a class="btn" ng-click="remove(item)">Delete</a>

然后在控制器中:

$scope.remove = function(item) { 
  var index = $scope.bdays.indexOf(item);
  $scope.bdays.splice(index, 1);     
}

Angular 会自动检测bdays数组的变化并更新ng-repeat

演示:http ://plnkr.co/edit/ZdShIA?p=preview

编辑:如果使用服务器进行实时更新将使用您创建的服务 $resource来管理阵列更新,同时它会更新服务器

于 2013-03-16T20:34:17.820 回答
54

这是一个正确的答案:

<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove=function($index){ 
  $scope.bdays.splice($index,1);     
}

在@charlietfl 的回答中。我认为这是错误的,因为您将$index其作为参数传递,但您在控制器中使用了愿望。如我错了请纠正我 :)

于 2013-08-29T08:17:30.617 回答
27

如果您在 ng-repeat 中

你可以使用一个班轮选项

    <div ng-repeat="key in keywords"> 
        <button ng-click="keywords.splice($index, 1)">

            {{key.name}}
        </button>
    </div>

$index被 angular 用来显示内部数组的当前索引ng-repeat

于 2015-09-22T15:08:39.297 回答
24

在基本情况下使用$index效果很好,@charlietfl 的回答很棒。但有时,$index还不够。

想象一下,您有一个数组,以两个不同的 ng-repeat 呈现。其中一个 ng-repeat 被过滤为具有真实属性的对象,另一个被过滤为虚假属性。展示了两个不同的过滤数组,它们源自一个原始数组。(或者,如果它有助于可视化:也许您有一个人数组,并且您想要一个 ng-repeat 用于该数组中的女性,另一个用于同一数组中的男性。)您的目标:从原始数组,使用来自过滤数组成员的信息。

在每个过滤后的数组中, $index 不会是原始数组中项目的索引。它将是过滤后的子数组中的索引。因此,您将无法知道原始people数组中的人的索引,您只能知道womenormen子数组中的 $index。尝试使用它来删除,除了你想要的地方,你的项目会从任何地方消失。该怎么办?

如果您足够幸运,使用的数据模型包含每个对象的唯一标识符,那么请使用它而不是 $index,splice从主数组中查找对象和它。(在下面使用我的示例,但使用该唯一标识符。)但是,如果您不那么幸运呢?

Angular 实际上用一个名为$$hashKey. 您可以在原始数组中搜索$$hashKey要删除的项目的匹配项,然后以这种方式摆脱它。

请注意,这$$hashKey是一个实现细节,未包含在已发布的 ng-repeat API 中。他们可以随时取消对该属性的支持。但可能不是。:-)

$scope.deleteFilteredItem = function(hashKey, sourceArray){
  angular.forEach(sourceArray, function(obj, index){
    // sourceArray is a reference to the original array passed to ng-repeat, 
    // rather than the filtered version. 
    // 1. compare the target object's hashKey to the current member of the iterable:
    if (obj.$$hashKey === hashKey) {
      // remove the matching item from the array
      sourceArray.splice(index, 1);
      // and exit the loop right away
      return;
    };
  });
}

调用:

ng-click="deleteFilteredItem(item.$$hashKey, refToSourceArray)"

编辑:使用这样的函数,$$hashKey而不是特定于模型的属性名称,还具有使该函数可在不同模型和上下文中重用的显着附加优势。为它提供您的数组引用和您的项目引用,它应该可以正常工作。

于 2013-12-11T05:43:16.053 回答
10

我通常用这样的风格写作:

<a class="btn" ng-click="remove($index)">Delete</a>


$scope.remove = function(index){
  $scope.[yourArray].splice(index, 1)
};

希望这会有所帮助您必须在 $scope 和 [yourArray] 之间使用点(。)

于 2015-01-13T14:37:49.417 回答
9

基于公认的答案,这将与 一起工作ngRepeatfilter并更好地处理期望:

控制器:

vm.remove = function(item, array) {
  var index = array.indexOf(item);
  if(index>=0)
    array.splice(index, 1);
}

看法:

ng-click="vm.remove(item,$scope.bdays)"
于 2015-09-09T15:20:52.457 回答
4

没有控制器的实现。

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<script>
  var app = angular.module("myShoppingList", []); 
</script>

<div ng-app="myShoppingList"  ng-init="products = ['Milk','Bread','Cheese']">
  <ul>
    <li ng-repeat="x in products track by $index">{{x}}
      <span ng-click="products.splice($index,1)">×</span>
    </li>
  </ul>
  <input ng-model="addItem">
  <button ng-click="products.push(addItem)">Add</button>
</div>

<p>Click the little x to remove an item from the shopping list.</p>

</body>
</html>

splice() 方法在数组中添加/删除项目。

array.splice(index, howmanyitem(s), item_1, ....., item_n)

索引:必需。一个整数,指定在什么位置添加/删除项目,使用负值指定从数组末尾开始的位置。

howmanyitem(s):可选。要删除的项目数。如果设置为 0,则不会删除任何项目。

item_1, ..., item_n:可选。要添加到数组中的新项目

于 2017-09-11T16:13:27.997 回答
3

我不同意您应该在控制器上调用方法。您应该为任何实际功能使用服务,并且应该为任何功能定义指令以实现可伸缩性和模块化,并分配一个单击事件,其中包含对您注入指令的服务的调用。

因此,例如,在您的 HTML...

<a class="btn" ng-remove-birthday="$index">Delete</a>

然后,创建一个指令...

angular.module('myApp').directive('ngRemoveBirthday', ['myService', function(myService){
    return function(scope, element, attrs){
        angular.element(element.bind('click', function(){
            myService.removeBirthday(scope.$eval(attrs.ngRemoveBirthday), scope);  
        };       
    };
}])

然后为您服务...

angular.module('myApp').factory('myService', [function(){
    return {
        removeBirthday: function(birthdayIndex, scope){
            scope.bdays.splice(birthdayIndex);
            scope.$apply();
        }
    };
}]);

当您像这样正确编写代码时,您将可以非常轻松地编写未来的更改,而无需重新构建代码。它组织得当,您可以通过使用自定义指令绑定来正确处理自定义点击事件。

例如,如果您的客户说,“嘿,现在让我们让它调用服务器并制作面包,然后弹出一个模式。” 您将能够轻松地访问服务本身,而无需添加或更改任何 HTML 和/或控制器方法代码。如果您在控制器上只有一条线路,您最终需要使用一项服务,以将功能扩展到客户要求的更重的提升。

此外,如果您在其他地方需要另一个“删除”按钮,您现在有一个指令属性(“ng-remove-birthday”),您可以轻松地将其分配给页面上的任何元素。现在这使其模块化和可重用。这在处理 Angular 2.0 的 HEAVY Web 组件范例时会派上用场。2.0 中没有控制器。:)

开发愉快!!!

于 2016-02-19T20:11:50.403 回答
1

这是另一个答案。我希望它会有所帮助。

<a class="btn" ng-click="delete(item)">Delete</a>

$scope.delete(item){
 var index = this.list.indexOf(item);
                this.list.splice(index, 1);   
}

array.splice(start)
array.splice(start, deleteCount)
array.splice(start, deleteCount, item1, item2, ...)

完整源代码在这里
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

于 2017-03-27T09:08:04.357 回答
0

如果您的项目中有 ID 或任何特定字段,则可以使用 filter()。它的行为类似于 Where()。

<a class="btn" ng-click="remove(item)">Delete</a>

在控制器中:

$scope.remove = function(item) { 
  $scope.bdays = $scope.bdays.filter(function (element) {
                    return element.ID!=item.ID
                });
}
于 2018-07-28T06:22:45.823 回答
0
Pass the id that you want to remove from the array to the given function 

来自控制器(功能可以在同一个控制器中,但更喜欢将其保留在服务中)

    function removeInfo(id) {
    let item = bdays.filter(function(item) {
      return bdays.id=== id;
    })[0];
    let index = bdays.indexOf(item);
    data.device.splice(indexOfTabDetails, 1);
  }
于 2019-07-10T09:59:16.133 回答
0

一种简单的内联方法就是添加bdays.splice($index, 1)删除按钮。

  <ul ng-repeat="bday in bdays">
  <li>
    <span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
    <form ng-show="editing" ng-submit="editing = false">
      <label>Name:</label>
      <input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
      <label>Date:</label>
      <input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
      <br/>
      <button class="btn" type="submit">Save</button>
      <a class="btn" ng-click="bdays.splice($index, 1)">Delete</a>
    </form>
  </li>
</ul>
于 2021-03-15T14:01:56.603 回答