Как удалить элементы / узлы из углового.массив 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 правильно? Он отлично работает, но загружает все элементы. Потому что все ключи массива сместились. Это создает ненужное отставание в мобильном приложении, которое я создаю..

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

12 67

12 ответов:

там нет ракетостроения в удалении элементов из массива. Для удаления элементов из любого массива необходимо использовать 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);
  }
}

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

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

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

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

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

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

кстати, я предполагаю, что вы пытаетесь удалить элемент на должность Я а не первый элемент массива. ($scope.items.shift(); в вашем коде будет удален первый элемент массива)

for(var i = $scope.items.length - 1; i >= 0; i--){
    if($scope.items[i].name == 'ted'){
        $scope.items.splice(i,1);
    }
}

здесь filter С библиотеку Underscore может помочь вам, мы удаляем элемент с именем "Тэд"

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

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

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

мне понравилось решение, предоставленное @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);
  }
}

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

  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 сайт Джона отставки

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

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

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

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

список param называется предметы. Парам х.сделал укажите, будет ли элемент удален. Надеюсь помочь вам. Приветствия.

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

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

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

мои элементы имеют уникальные идентификаторы. Я удаляю одним путем фильтрации модель с 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;}
  );
}

в качестве идентификатора вы также можете использовать свойство $$hashKey ваших элементов модели:$$hashKey:"object:91"