Html 如何使用 ng-click 从数组中删除项目或对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15453979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 06:33:58  来源:igfitidea点击:

How do I delete an item or object from an array using ng-click?

htmlangularjsedit

提问by Jess McKenzie

I am trying to write a function that enables me to remove an item when the button is clicked but I think I am getting confused with the function - do I use $digest?

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

HTML & app.js:

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

回答by charlietfl

To remove item you need to remove it from array and can pass bdayitem to your remove function in markup. Then in controller look up the index of item and remove from array

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

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

Then in controller:

然后在控制器中:

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

Angular will automatically detect the change to the bdaysarray and do the update of ng-repeat

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

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

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

EDIT: If doing live updates with server would use a service you create using $resourceto manage the array updates at same time it updates server

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

回答by Dzung Nguyen

This is a correct answer:

这是一个正确的答案:

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

In @charlietfl's answer. I think it's wrong since you pass $indexas paramter but you use the wish instead in controller. Correct me if I'm wrong :)

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

回答by azerafati

In case you're inside an ng-repeat

如果您在 ng-repeat 中

you could use a one liner option

你可以使用单衬选项

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

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

$indexis used by angular to show current index of the array inside ng-repeat

$indexangular 使用它来显示内部数组的当前索引 ng-repeat

回答by XML

Using $indexworks perfectly well in basic cases, and @charlietfl's answer is great. But sometimes, $indexisn't enough.

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

Imagine you have a single array, which you're presenting in two different ng-repeat's. One of those ng-repeat's is filtered for objects that have a truthy property, and the other is filtered for a falsy property. Two different filtered arrays are being presented, which derive from a single original array. (Or, if it helps to visualize: perhaps you have a single array of people, and you want one ng-repeat for the women in that array, and another for the men in that same array.) Your goal: delete reliably from the original array, using information from the members of the filtered arrays.

想象一下你有一个数组,你用两个不同的 ng-repeat 来呈现它。这些 ng-repeat 的一个被过滤为具有真实属性的对象,另一个被过滤为虚假属性。正在呈现两个不同的过滤数组,它们源自单个原始数组。(或者,如果它有助于形象化:也许您只有一个人数组,并且您希望该数组中的女性有一个 ng-repeat ,同一数组中的男性有另一个 ng-repeat 。)您的目标:从原始数组,使用来自过滤数组成员的信息。

In each of those filtered arrays, $index won't be the index of the item within the original array. It'll be the index in the filtered sub-array. So, you won't be able to tell the person's index in the original peoplearray, you'll only know the $index from the womenor mensub-array. Try to delete using that, and you'll have items disappearing from everywhere except where you wanted. What to do?

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

If you're lucky enough be using a data model includes a unique identifier for each object, then use that instead of $index, to find the object and spliceit out of the main array. (Use my example below, but with that unique identifier.) But if you're not so lucky?

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

Angular actually augments each item in an ng-repeated array (in the main, original array) with a unique property called $$hashKey. You can search the original array for a match on the $$hashKeyof the item you want to delete, and get rid of it that way.

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

Note that $$hashKeyis an implementation detail, not included in the published API for ng-repeat. They could remove support for that property at any time. But probably not. :-)

请注意,这$$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;
    };
  });
}

Invoke with:

调用:

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


EDIT: Using a function like this, which keys on the $$hashKeyinstead of a model-specific property name, also has the significant added advantage of making this function reusable across different models and contexts. Provide it with your array reference, and your item reference, and it should just work.

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

回答by Sviatoslav Novosiadlyj

I usually write in such style :

我通常以这种风格写作:

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


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

Hope this will help You have to use a dot(.) between $scope and [yourArray]

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

回答by Joan-Diego Rodriguez

Building on the accepted answer, this will work with ngRepeat, filterand handle expections better:

基于已接受的答案,这将适用于ngRepeatfilter并更好地处理期望:

Controller:

控制器:

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

View:

看法:

ng-click="vm.remove(item,$scope.bdays)"

回答by Deepu Reghunath

implementation Without a Controller.

没有控制器的实现。

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

The splice() method adds/removes items to/from an array.

splice() 方法向/从数组添加/删除项目。

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

index: Required. An integer that specifies at what position to add/remove items, Use negative values to specify the position from the end of the array.

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

howmanyitem(s): Optional. The number of items to be removed. If set to 0, no items will be removed.

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

item_1, ..., item_n: Optional. The new item(s) to be added to the array

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

回答by Justin Russo

I disagree that you should be calling a method on your controller. You should be using a service for any actual functionality, and you should be defining directives for any functionality for scalability and modularity, as well as assigning a click event which contains a call to the service which you inject into your directive.

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

So, for instance, on your HTML...

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

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

Then, create a directive...

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

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

Then in your service...

然后在您的服务...

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

When you write your code properly like this, you will make it very easy to write future changes without having to restructure your code. It's organized properly, and you're handling custom click events correctly by binding using custom directives.

当您像这样正确地编写代码时,您将很容易编写未来的更改,而无需重构代码。它被正确组织,并且您通过使用自定义指令绑定来正确处理自定义点击事件。

For instance, if your client says, "hey, now let's make it call the server and make bread, and then popup a modal." You will be able to easily just go to the service itself without having to add or change any of the HTML, and/or controller method code. If you had just the one line on the controller, you'd eventually need to use a service, for extending the functionality to the heavier lifting the client is asking for.

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

Also, if you need another 'Delete' button elsewhere, you now have a directive attribute ('ng-remove-birthday') you can easily assign to any element on the page. This now makes it modular and reusable. This will come in handy when dealing with the HEAVY web components paradigm of Angular 2.0. There IS no controller in 2.0. :)

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

Happy Developing!!!

快乐发展!!!

回答by Bahodir Boydedayev

Here is another answer. I hope it will help.

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

<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, ...)

Full source is here
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

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

回答by Seyed Reza Dadrezaei

if you have ID or any specific field in your item, you can use filter(). its act like Where().

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

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

in controller:

在控制器中:

$scope.remove = function(item) { 
  $scope.bdays = $scope.bdays.filter(function (element) {
                    return element.ID!=item.ID
                });
}