web-dev-qa-db-fra.com

Comment supprimer des éléments / nœuds du tableau angular.js

J'essaie de supprimer des éléments du tableau $scope.items afin que les éléments soient supprimés dans la vue ng-repeat="item in items"

Juste à des fins de démonstration, voici un code:

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

Je veux supprimer le 1er élément de la vue s'il y a le nom ted non? Cela fonctionne bien, mais la vue recharge tous les éléments. Parce que toutes les clés du tableau ont changé. Cela crée un décalage inutile dans l'application mobile que je crée.

Quelqu'un a une solution à ce problème?

69
TheNickyYo

Il n'y a aucune science de fusée dans la suppression d'éléments de array. Pour supprimer des éléments de n'importe quel tableau, vous devez utiliser splice : $scope.items.splice(index, 1);. Voici un exemple :

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

Pour quiconque revient à cette question. Le "moyen angulaire" correct pour supprimer des éléments d'un tableau est avec le filtre $. Il suffit d’injecter $ filter dans votre contrôleur et de procéder comme suit:

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

Vous n'avez pas besoin de charger d'autres bibliothèques ni de recourir à des primitives Javascript.

120
bpaul

Vous pouvez utiliser du javascript simple - Array.prototype.filter ()

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

Parce que lorsque vous faites shift() sur un tableau, cela change la longueur du tableau. Donc, la boucle for va être foirée. Vous pouvez effectuer une boucle de bout en bout pour éviter ce problème.

Btw, je suppose que vous essayez de supprimer l'élément à la position i plutôt que le premier élément du tableau. ($scope.items.shift(); dans votre code supprimera le premier élément du tableau)

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

Voici filter avec nderscore library pourrait vous aider, nous supprimons l'élément avec le nom "ted"

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

Juste une légère expansion sur la solution "angulaire". Je voulais exclure un élément en fonction de son identifiant numérique, donc le! l'approche ne fonctionne pas. La solution plus générale qui devrait fonctionner pour {name: 'ted'} ou {id: 42} est la suivante:

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

J'ai aimé la solution fournie par @madhead

Cependant, le problème que j’avais, c’est que cela ne fonctionnerait pas pour une liste triée. Ainsi, au lieu de passer l’index à la fonction delete, j’ai passé l’élément puis l’index via indexof.

par exemple.:

var index = $scope.items.indexOf(item);
$scope.items.splice(index, 1);

Vous trouverez ci-dessous une version mise à jour de l'exemple madheads: lien vers exemple

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

Ma solution à cela (qui n'a causé aucun problème de performances):

  1. Étendez l’objet tableau avec une méthode remove (je suis sûr que vous en aurez besoin plus d’une fois):
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);
};

Je l'utilise dans tous mes projets et les crédits vont à John Resig Site de John Resig

  1. Utiliser forEach et une vérification de base:
$scope.items.forEach(function(element, index, array){
          if(element.name === 'ted'){
              $scope.items.remove(index);
          }
        });

À la fin, le $ digest sera lancé dans angularjs et mon interface utilisateur sera mise à jour immédiatement, sans aucun retard identifiable.

3
Fer To

L'utilisation de la fonction indexOf ne l'a pas coupé dans ma collection de ressources REST.

J'ai dû créer une fonction qui récupère l'index de tableau d'une ressource située dans une collection de ressources:

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);
1
Stephane

Si une fonction est associée à la liste, l'association est également supprimée lorsque vous créez la fonction de raccordement. Ma solution:

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

La liste param est nommée articles. Le param x.done indiquer si l'élément sera supprimé. J'espère vous aider. Salutations.

1
Drako

Ma solution était assez simple

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);
    }
});
1
Bastin Robin

Mes articles ont des identifiants uniques. J'en supprime un en filtrant le modèle avec des angles $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;}
  );
}

En tant qu'id, vous pouvez également utiliser la propriété $$ hashKey de vos éléments de modèle: $$hashKey:"object:91"

0
Ruwen