Как удалить элементы/узлы из массива 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
- Использование 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"