Как удалить элемент или объект из массива с помощью ng-click?
Я пытаюсь написать функцию, которая позволяет мне удалить элемент при нажатии кнопки, но я думаю, что меня путают с функцией - я использую $digest
?
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();
};
Ответы
Ответ 1
Чтобы удалить элемент, вам нужно удалить его из массива и передать элемент bday
в функцию удаления в разметке. Затем в контроллере найдите индекс элемента и удалите из массива
<a class="btn" ng-click="remove(item)">Delete</a>
Затем в контроллере:
$scope.remove = function(item) {
var index = $scope.bdays.indexOf(item);
$scope.bdays.splice(index, 1);
}
Angular автоматически обнаружит изменение в массиве bdays
и выполнит обновление ng-repeat
DEMO: http://plnkr.co/edit/ZdShIA?p=preview
РЕДАКТИРОВАТЬ: Если при выполнении живых обновлений с сервером будет использоваться служба, которую вы создаете с помощью $resource
, чтобы управлять обновлениями массива одновременно, он обновляет сервер
Ответ 2
Это правильный ответ:
<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove=function($index){
$scope.bdays.splice($index,1);
}
В ответе @charlietfl. Я считаю это неправильным, так как вы передаете $index
как параметр, но вместо этого вы используете желание вместо этого в контроллере. Исправьте меня, если я ошибаюсь:)
Ответ 3
, если вы находитесь внутри ng-repeat
вы можете использовать опцию с одним лайнером
<div ng-repeat="key in keywords">
<button ng-click="keywords.splice($index, 1)">
{{key.name}}
</button>
</div>
$index
используется angular для отображения текущего индекса массива внутри ng-repeat
Ответ 4
Использование $index
отлично работает в основных случаях, а ответ @charlietfl велик. Но иногда, $index
недостаточно.
Представьте, что у вас есть один массив, который вы представляете в двух разных ng-repeat. Один из этих ng-repeat фильтруется для объектов, которые имеют правдивое свойство, а другое фильтруется для свойства falsy. Представляются два разных фильтрованных массива, которые выводятся из одного исходного массива. (Или, если это помогает визуализировать: возможно, у вас есть один массив людей, и вы хотите один ng-repeat для женщин в этом массиве, а другой для мужчин в том же массиве.) Ваша цель: надежно удалить из исходный массив, используя информацию от членов фильтрованных массивов.
В каждом из фильтрованных массивов индекс $index не будет индексом элемента в исходном массиве. Это будет индекс в отфильтрованном подматрице. Таким образом, вы не сможете сообщить индексу человека в исходном массиве people
, вы будете знать только индекс $из подматрицы women
или men
. Попытайтесь удалить, используя это, и у вас будут предметы, исчезающие везде, кроме тех, где вы хотели. Что делать?
Если вам посчастливилось использовать модель данных, она содержит уникальный идентификатор для каждого объекта, а затем используйте вместо $index, чтобы найти объект и splice
его из основного массива. (Используйте мой пример ниже, но с этим уникальным идентификатором.) Но если вам не повезло?
Angular фактически увеличивает каждый элемент в ng-повторном массиве (в основном, исходном массиве) с уникальным свойством $$hashKey
. Вы можете искать исходный массив для соответствия на $$hashKey
элемента, который хотите удалить, и избавиться от него таким образом.
Обратите внимание, что $$hashKey
- это деталь реализации, не включенная в опубликованный API для ng-repeat. Они могут удалить поддержку этого имущества в любое время. Но, вероятно, нет.: -)
$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 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;
};
});
}
Вызов с помощью:
ng-click="deleteFilteredItem(item.$$hashKey, refToSourceArray)"
EDIT: использование такой функции, что ключи в $$hashKey
вместо имени свойства модели также имеют значительное дополнительное преимущество, заключающееся в том, что эту функцию можно использовать повторно для разных моделей и контекстов. Предоставьте ему ссылку на массив и ссылку на ваш объект, и он должен просто работать.
Ответ 5
Я обычно пишу в таком стиле:
<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove = function(index){
$scope.[yourArray].splice(index, 1)
};
Надеюсь, это поможет Вам использовать точку (.) Между $ scope и [yourArray]
Ответ 6
Основываясь на принятом ответе, это будет работать с ngRepeat
, filter
и лучше обработать прогнозы:
Контроллер:
vm.remove = function(item, array) {
var index = array.indexOf(item);
if(index>=0)
array.splice(index, 1);
}
Вид:
ng-click="vm.remove(item,$scope.bdays)"
Ответ 7
реализация без контроллера.
<!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>
Ответ 8
Я не согласен с тем, что вы должны вызывать метод на вашем контроллере. Вы должны использовать сервис для любых фактических функций, и вы должны определять директивы для любых функций масштабируемости и модульности, а также назначать событие click, которое содержит вызов службы, которую вы вводите в свою директиву.
Так, например, на вашем HTML...
<a class="btn" ng-remove-birthday="$index">Delete</a>
Затем создайте директиву...
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);
};
};
}])
Затем в вашем сервисе...
angular.module('myApp').factory('myService', [function(){
return {
removeBirthday: function(birthdayIndex, scope){
scope.bdays.splice(birthdayIndex);
scope.$apply();
}
};
}]);
Когда вы правильно пишете свой код, вы легко сможете писать будущие изменения, не переделывая свой код. Он организован правильно, и вы правильно обрабатываете пользовательские события кликов, связывая их с помощью пользовательских директив.
Например, если ваш клиент говорит: "Эй, теперь позвольте заставить его вызвать сервер и сделать хлеб, а затем всплывать модальный". Вы сможете легко просто перейти к самой службе без необходимости добавлять или изменять какой-либо код кода HTML и/или контроллера. Если бы у вас была только одна строка на контроллере, вам в конечном итоге нужно было бы использовать сервис, чтобы расширить функциональность до более тяжелого подъема, который просит клиент.
Кроме того, если вам нужна другая кнопка "Удалить" в другом месте, теперь у вас есть атрибут директивы ( "ng-remove-birthday" ), который вы можете легко назначить любому элементу на странице. Это теперь делает его модульным и многоразовым. Это пригодится при работе с парадигмой веб-компонентов HEAVY Angular 2.0. В 2.0 нет контроллера.:)
Счастливое развитие!!!
Ответ 9
Вот еще один ответ. Надеюсь, это поможет.
<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, ...)
Полный источник находится здесь
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
Ответ 10
если у вас есть идентификатор или какое-либо конкретное поле в вашем элементе, вы можете использовать filter(). его действие как где().
<a class="btn" ng-click="remove(item)">Delete</a>
в контроллере:
$scope.remove = function(item) {
$scope.bdays = $scope.bdays.filter(function (element) {
return element.ID!=item.ID
});
}
Ответ 11
Pass the id that you want to remove from the array to the given function
от контроллера (функция может быть в том же контроллере, но предпочитать хранить ее в сервисе)
function removeInfo(id) {
let item = bdays.filter(function(item) {
return bdays.id=== id;
})[0];
let index = bdays.indexOf(item);
data.device.splice(indexOfTabDetails, 1);
}