Как удалить элементы/узлы из массива angular.js

Я пытаюсь удалить элементы из массива $scope.items, чтобы элементы были удалены в представлении ng-repeat="item in items"

Для демонстрационных целей здесь приведен код:

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

Я хочу удалить 1-й элемент из представления, если есть имя ted справа? Он отлично работает, но представление перезагружает все элементы. Потому что все клавиши массива сдвинуты. Это создает ненужное отставание в мобильном приложении, которое я создаю.

У кого-нибудь есть решения этой проблемы?

Ответ 1

В удалении элементов из массива нет ракетостроения. Чтобы удалить элементы из любого массива, вам необходимо использовать splice: $scope.items.splice(index, 1);. Вот пример:

HTML

<!DOCTYPE html>
<html data-ng-app="demo">
  <head>
    <script data-require="[email protected]" 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);
  }
}

Ответ 2

Для тех, кто возвращается к этому вопросу. Правильный "Angular путь" для удаления элементов из массива имеет $filter. Просто введите $filter в свой контроллер и выполните следующие действия:

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

Вам не нужно загружать дополнительные библиотеки или использовать примитивы Javascript.

Ответ 3

Вы можете использовать простой javascript - Array.prototype.filter()

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

Ответ 4

Потому что, когда вы выполняете shift() в массиве, он меняет длину массива. Таким образом, цикл for будет испорчен. Чтобы избежать этой проблемы, вы можете прокручиваться с конца на передний план.

Btw, я предполагаю, что вы попытаетесь удалить элемент в позиции 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);
    }
}

Ответ 5

Вот filter с библиотека поддеревьев может помочь вам, мы удалим элемент с именем "ted"

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

Ответ 6

Просто небольшое расширение в решении angular. Я хотел исключить элемент на основе его числового id, так что! подход не работает. Более общее решение, которое должно работать для {name: 'ted'} или {id: 42}, следующее:

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

Ответ 7

Мне понравилось решение, предоставленное @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="[email protected]" 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);
  }
}

Ответ 8

Мое решение для этого (что не вызвало каких-либо проблем с производительностью):

  • Расширьте объект массива методом удаления (я уверен, что вам понадобится его больше, чем один раз):
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 Site

  1. Использование forEach и базовой проверки:
$scope.items.forEach(function(element, index, array){
          if(element.name === 'ted'){
              $scope.items.remove(index);
          }
        });

В конце $digest будет запущен в angularjs, и мой пользовательский интерфейс будет обновлен немедленно без какого-либо узнаваемого запаздывания.

Ответ 9

Если у вас есть функция, связанная с списком, когда вы создаете функцию сращивания, ассоциация также удаляется. Мое решение:

$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 указывает, будет ли элемент удален. Надеюсь вам помочь. Привет.

Ответ 10

Использование функции 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);

Ответ 11

Мое решение было довольно прямым.

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

Ответ 12

Мои объекты имеют уникальный идентификатор. Я удаляю его, фильтруя модель с помощью углов $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"