Как удалить динамически добавленные объекты из массива с помощью кнопки, связанной с каждым объектом?

Я использую Angular для создания приложения со списком покупок. У меня есть два предварительно созданных списка, каждый из которых содержит два и три предварительно созданных элемента соответственно для целей тестирования. Конечно, в конечном итоге не будет предварительно созданных элементов или списков. Все должно динамически добавляться пользователем. Мне удалось заставить работать кнопку «Добавить элемент», чтобы вы могли добавлять новый элемент в каждый список.

Вот ручка, с которой можно поэкспериментировать: http://codepen.io/anon/pen/WraZEv

<body ng-controller="notepadController as notepad">
    <header ng-repeat="list in notepad.lists">
        <div>Delete list</div>
        <h1>{{list.name}}</h1>
    </header>
    <div ng-repeat="list in notepad.lists" class="shoppingList" ng-controller="ItemController as itemCtrl">
        <ul>
            <li ng-repeat="item in list.items">
                <label>
                    <input type="checkbox" ng-model="item.checked">
                    {{item.name}}
                </label>
                <form name="removeItemForm" ng-submit="itemCtrl.removeItem(list)">
                    <input type="submit" value="Remove Item">
                </form>
            </li>
        </ul>
        <form name="itemForm" ng-submit="itemCtrl.addItem(list)">
            <input type="text" ng-model="itemCtrl.item.name">
            <input type="submit" value="Add Item">
        </form>
    </div>
</body>

Javascript это:

(function(){
var app = angular.module('notepadApp', []);

var shoppingLists = [
    {
        name: 'groceries',
        items: [
            {
                name: 'milk',
                checked: false
            },
            {
                name: 'eggs',
                checked: false
            }
        ]
    },
    {
        name: 'cvs',
        items: [
            {
                name: 'pills',
                checked: false
            },
            {
                name: 'cotton balls',
                checked: false
            },
            {
                name: 'cigs',
                checked: false
            }
        ]
    }
];

app.controller('notepadController', function(){
    this.lists = shoppingLists;
});

app.controller('ItemController', function(){
    this.item = {};

    // add new item to a shopping list
    this.addItem = function(list){
        list.items.push(this.item);
        this.item = {};
    };

    // remove an item from a shopping list
    this.removeItem = function(list){
        var listOfItems = [];

        var i;

        for (i = 0; i < list.items.length; i++){
            list.items.splice(list.items[i,1]);
        }
    };
});
})();

Кнопка «Удалить элемент» удаляет все элементы из списка, а не элемент, с которым он связан. Я понимаю, почему он это делает, но я не могу понять, как получить индекс элемента, который нужно удалить, и чтобы кнопка «Удалить элемент» удаляла только этот элемент.


person Community    schedule 06.02.2016    source источник
comment
.splice потребуется 2 аргумента. Первый index второй number of items to be removed   -  person Rayon    schedule 06.02.2016
comment
@Rayon Dabre исправлено   -  person    schedule 06.02.2016
comment
Попробуйте это: jsfiddle.net/ffa5jw42   -  person Rayon    schedule 06.02.2016
comment
@RayonDabre вы должны опубликовать как ответ   -  person    schedule 06.02.2016


Ответы (1)


Давайте немного подумаем об этом. У вас есть два контроллера. Один содержит список, а другой содержит логику элемента.

Прежде всего, если вы хотите изменить list, функции, которые его изменяют, должны находиться в том же контроллере, что и list.

В настоящее время вы застряли при передаче всего списка из-за того, как вы настроили контроллеры. Я думаю, вы начинаете понимать, что не так с этим подходом.

Начнем с повторителя

ng-repeat="item in list"

Это дает вам item, это то, что вы хотите передать в функцию.

Точно так же, как вы получаете доступ к item для вывода name, вы можете использовать это для передачи в ваш removeItem.

<form name="removeItemForm" ng-submit="notepad.removeItem(item)">
  <input type="submit" value="Remove Item">
</form>

Вы хотите, чтобы removeItem жил в том же контроллере, что и ваш список. (обратите внимание, я изменил itemCtrl.removeItem на notepad.removeItem.

In notepadController:

this.removeItem = function(item){
  var index = this.list.indexOf(item);
  if (index > -1) {
    this.list.splice(index, 1); // remove the item
  }
};

ng-repeat также позволяет вам использовать переменную с именем $index, вы также можете использовать ее для предоставления index, которое вы хотите удалить из list:

ng-submit="notpad.removeItem($index)

и тогда метод будет выглядеть так

this.removeItem = function(index) {
  this.list.splice(index, 1);
}
person Atticus    schedule 06.02.2016
comment
Мне пришлось изменить ваши решения. Для первого мне пришлось передать в функцию как list, так и item. Мне также пришлось удалить this.. Я также добавил items к list, чтобы он читался как list.items.indexOf(item) и list.items.splice. - person ; 06.02.2016
comment
Для второго решения мне пришлось удалить this. плюс передать как list, так и index (и передать list и $index в атрибуте ng-submit). Я также добавил сюда items - list.items.splice - person ; 06.02.2016
comment
Хорошее объяснение подхода и концепции, хотя - person ; 06.02.2016