如何从angular.js数组中删除元素/节点

时间:2013-08-18 19:50:14

标签: angularjs scope angularjs-ng-repeat

我正在尝试从数组$scope.items中删除元素,以便在视图ng-repeat="item in items"

中删除项目

仅出于演示目的,这里有一些代码:

for(i=0;i<$scope.items.length;i++){
    if($scope.items[i].name == 'ted'){
      $scope.items.shift();
    }
}

如果名称为ted,我想从视图中删除第一个元素吗?它工作正常,但视图重新加载所有元素。因为所有数组键都已移位。这会在我创建的移动应用中产生不必要的延迟..

任何人都有这个问题的解决方案吗?

12 个答案:

答案 0 :(得分:132)

从数组中删除项目没有火箭科学。要从任何阵列中删除项目,您需要使用splice$scope.items.splice(index, 1);Here is an example

<强> HTML

<!DOCTYPE html>
<html data-ng-app="demo">
  <head>
    <script data-require="angular.js@1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body>
    <div data-ng-controller="DemoController">
      <ul>
        <li data-ng-repeat="item in items">
          {{item}}
          <button data-ng-click="removeItem($index)">Remove</button>
        </li>
      </ul>
      <input data-ng-model="newItem"><button data-ng-click="addItem(newItem)">Add</button>
    </div>
  </body>
</html>

<强>的JavaScript

"use strict";

var demo = angular.module("demo", []);

function DemoController($scope){
  $scope.items = [
    "potatoes",
    "tomatoes",
    "flour",
    "sugar",
    "salt"
  ];

  $scope.addItem = function(item){
    $scope.items.push(item);
    $scope.newItem = null;
  }

  $scope.removeItem = function(index){
    $scope.items.splice(index, 1);
  }
}

答案 1 :(得分:119)

对于任何回到这个问题的人。从数组中删除项目的正确“Angular Way”是$ filter。只需将$ filter注入控制器并执行以下操作:

$scope.items = $filter('filter')($scope.items, {name: '!ted'})

您无需加载任何其他库或使用Javascript原语。

答案 2 :(得分:14)

您可以使用简单的javascript - Array.prototype.filter()

$scope.items = $scope.items.filter(function(item) {
    return item.name !== 'ted';
});

答案 3 :(得分:11)

因为当您在数组上执行shift()时,它会更改数组的长度。因此for循环将被搞砸。您可以从头到尾遍历 以避免此问题。

顺便说一下,我假设您尝试删除 i 位置的元素,而不是数组的第一个元素。 (代码中的$scope.items.shift();将删除数组的第一个元素)

for(var i = $scope.items.length - 1; i >= 0; i--){
    if($scope.items[i].name == 'ted'){
        $scope.items.splice(i,1);
    }
}

答案 4 :(得分:8)

以下filter Underscore library 可能会对您有帮助,我们会移除名为“ted”的项目

$scope.items = _.filter($scope.items, function(item) {
    return !(item.name == 'ted');
 });

答案 5 :(得分:6)

对'angular'解决方案稍作扩展。我想根据它的数字ID排除一个项目,所以!方法不起作用。 适用于{name:'ted'}或{id:42}的更通用的解决方案是:

mycollection = $filter('filter')(myCollection, { id: theId }, function (obj, test) { 
                                                             return obj !== test; });

答案 6 :(得分:5)

我喜欢@madhead

提供的解决方案

但是我遇到的问题是它不适用于排序列表,所以我没有将索引传递给删除函数,而是传递了项目,然后通过indexof得到了索引

e.g:

var index = $scope.items.indexOf(item);
$scope.items.splice(index, 1);

madheads示例的更新版本如下: link to example

<强> HTML

<!DOCTYPE html>
<html data-ng-app="demo">
  <head>
    <script data-require="angular.js@1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body>
    <div data-ng-controller="DemoController">
      <ul>
        <li data-ng-repeat="item in items|orderBy:'toString()'">
          {{item}}
          <button data-ng-click="removeItem(item)">Remove</button>
        </li>
      </ul>
      <input data-ng-model="newItem"><button data-ng-click="addItem(newItem)">Add</button>
    </div>
  </body>
</html>

<强>的JavaScript

"use strict";

var demo = angular.module("demo", []);

function DemoController($scope){
  $scope.items = [
    "potatoes",
    "tomatoes",
    "flour",
    "sugar",
    "salt"
  ];

  $scope.addItem = function(item){
    $scope.items.push(item);
    $scope.newItem = null;
  }

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

答案 7 :(得分:3)

我的解决方案(没有引起任何性能问题):

  1. 使用方法删除扩展数组对象(我确定您不仅需要一次):
  2. Array.prototype.remove = function(from, to) {
      var rest = this.slice((to || from) + 1 || this.length);
      this.length = from < 0 ? this.length + from : from;
      return this.push.apply(this, rest);
    };
    

    我在我的所有项目中使用它,并将信用转到John Resig John Resig's Site

    1. 使用forEach和基本检查:
    2. $scope.items.forEach(function(element, index, array){
                if(element.name === 'ted'){
                    $scope.items.remove(index);
                }
              });
      

      最后,$ digest将在angularjs中触发,我的UI立即更新,没有任何可识别的延迟。

答案 8 :(得分:1)

如果您具有与列表关联的任何功能,则在创建拼接功能时,也会删除关联。我的解决方案:

$scope.remove = function() {
    var oldList = $scope.items;
    $scope.items = [];

    angular.forEach(oldList, function(x) {
        if (! x.done) $scope.items.push( { [ DATA OF EACH ITEM USING oldList(x) ] });
    });
};

列表参数名为项目。 param x.done 表示该项目是否将被删除。希望能帮助你。问候。

答案 9 :(得分:1)

使用indexOf函数并没有削减我的REST资源集合。

我必须创建一个函数来检索位于资源集合中的资源的数组索引:

factory.getResourceIndex = function(resources, resource) {
  var index = -1;
  for (var i = 0; i < resources.length; i++) {
    if (resources[i].id == resource.id) {
      index = i;
    }
  }
  return index;
}

$scope.unassignedTeams.splice(CommonService.getResourceIndex($scope.unassignedTeams, data), 1);

答案 10 :(得分:1)

My solution was quite straight forward

app.controller('TaskController', function($scope) {
 $scope.items = tasks;

    $scope.addTask = function(task) {
        task.created = Date.now();
        $scope.items.push(task);
        console.log($scope.items);
    };

    $scope.removeItem = function(item) {
        // item is the index value which is obtained using $index in ng-repeat
        $scope.items.splice(item, 1);
    }
});

答案 11 :(得分:0)

我的商品有唯一ID。我通过使用angulars $filter service:

过滤模型来删除一个
var myModel = [{id:12345, ...},{},{},...,{}];
...
// working within the item
function doSthWithItem(item){
... 
  myModel = $filter('filter')(myModel, function(value, index) 
    {return value.id !== item.id;}
  );
}

作为ID,您还可以使用模型项的$$ hashKey属性:$$hashKey:"object:91"