72

我正在尝试从数组中删除元素,$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,我想从视图中删除第一个元素,对吗?它工作正常,但视图重新加载所有元素。因为所有的数组键都发生了变化。这在我正在创建的移动应用程序中造成了不必要的延迟。

有人有解决这个问题的方法吗?

4

12 回答 12

137

从数组中删除项目没有火箭科学。要从任何数组中删除项目,您需要使用splice: $scope.items.splice(index, 1);这是一个例子

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);
  }
}
于 2013-08-18T20:25:31.080 回答
124

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

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

您不需要加载任何额外的库或诉诸 Javascript 原语。

于 2014-03-04T00:42:39.983 回答
16

您可以使用纯 javascript - Array.prototype.filter()

$scope.items = $scope.items.filter(function(item) {
    return item.name !== 'ted';
});
于 2014-02-23T18:42:44.163 回答
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);
    }
}
于 2013-08-18T20:26:39.953 回答
8

这里可能filterUnderscore library您有所帮助,我们删除名称为“ted”的项目

$scope.items = _.filter($scope.items, function(item) {
    return !(item.name == 'ted');
 });
于 2013-08-18T20:39:27.353 回答
6

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

mycollection = $filter('filter')(myCollection, { id: theId }, function (obj, test) { 
                                                             return obj !== test; });
于 2014-05-22T15:33:01.410 回答
5

我喜欢@madhead 提供的解决方案

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

例如:

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

madheads 示例的更新版本如下: 示例链接

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);
  }
}
于 2016-11-05T01:41:19.323 回答
3

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

  1. 使用 remove 方法扩展数组对象(我相信您不止一次需要它):
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 的网站

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

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

于 2014-10-08T09:35:35.523 回答
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) ] });
    });
};

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

于 2014-09-04T12:28:09.093 回答
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);
于 2014-09-17T07:43:35.327 回答
1

我的解决方案非常简单

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);
    }
});
于 2016-03-23T06:13:49.217 回答
0

我的物品有唯一的 ID。我通过使用 angulars$filter服务过滤模型来删除一个:

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"

于 2017-03-02T09:19:50.233 回答