154 votes

Comment supprimer un élément d'un tableau dans la portée d'AngularJS ?

Liste de tâches simple, mais avec un bouton de suppression sur la page de la liste pour chaque élément :

enter image description here

Modèle HTML pertinent :

<tr ng-repeat="person in persons">
  <td>{{person.name}} - # {{person.id}}</td>
  <td>{{person.description}}</td>
  <td nowrap=nowrap>
    <a href="#!/edit"><i class="icon-edit"></i></a>
    <button ng-click="delete(person)"><i class="icon-minus-sign"></i></button>
  </td>
</tr>

Méthode de contrôle pertinente :

$scope.delete = function (person) {
  API.DeletePerson({ id: person.id }, function (success) {
    // I need some code here to pull the person from my scope.
  });
};

J'ai essayé $scope.persons.pull(person) y $scope.persons.remove(person) .

Bien que la base de données ait été supprimée avec succès, je ne peux pas retirer cet élément de la portée et je ne veux pas faire un appel de méthode au serveur pour des données que le client a déjà, je veux juste retirer cette personne de la portée.

Des idées ?

0 votes

Je l'exécute avec $route, et la vue ne fonctionne pas bien. J'obtiens toujours une page vide après avoir effectué la suppression :-(

0 votes

Il ne s'agit pas tant de supprimer de la portée mais plutôt d'un tableau, et ce serait la même chose indépendamment d'angular, c'est juste du javascript

311voto

Joseph Silber Points 69582

Vous devrez trouver l'index de l'objet de l'enquête. person dans votre persons puis utilisez la fonction splice méthode :

$scope.persons.splice( $scope.persons.indexOf(person), 1 );

49 votes

Cette réponse est meilleure ; elle fonctionne lorsque la liste a été filtrée de sorte que l'index dans la vue n'est pas le même que celui du tableau dans la portée.

5 votes

C'est en effet la meilleure réponse. Notez qu'en plus du cas d'utilisation des listes filtrées mentionné par Andrew, cette approche couvre également le cas où vous supprimez plusieurs personnes et où les requêtes Ajax pour ces suppressions reviennent dans le désordre. Si vous avez utilisé les index de ligne avant le retour de l'appel Ajax, vous finirez par supprimer les mauvaises lignes.

4 votes

C'est mieux dans certains cas, mais avec indexOf vous devez itérer sur tous les éléments pour trouver le bon, dans la réponse de Josh vous obtenez l'index et l'élément plus rapidement.

260voto

Josh David Miller Points 66508

Votre problème ne concerne pas vraiment Angular, mais les méthodes Array. La bonne façon de supprimer un élément particulier d'un tableau est d'utiliser la méthode Array.splice . De plus, lorsque vous utilisez ng-repeat, vous avez accès à la fonction spéciale $index qui est l'index actuel du tableau que vous avez transmis.

La solution est en fait assez simple :

Voir :

<a ng-click="delete($index)">Delete</a>

Contrôleur :

$scope.delete = function ( idx ) {
  var person_to_delete = $scope.persons[idx];

  API.DeletePerson({ id: person_to_delete.id }, function (success) {
    $scope.persons.splice(idx, 1);
  });
};

1 votes

@ScottMalachowski Vous avez raison. J'ai oublié cette partie. J'ai révisé ma réponse pour refléter cela, afin qu'elle soit cohérente avec la vôtre.

13 votes

Attention - cette solution basée sur l'index ne fonctionnera pas si vous utilisez plusieurs ng-repeats du même objet dans une vue (par exemple Tâches programmées, Tâches non programmées, Tâches terminées, toutes issues de $scope.tasks) parce que vous aurez plusieurs éléments avec l'index 2, 3, 4, etc.

0 votes

Le commentaire ci-dessus, par @shacker, sur les multiples ng-repeats avec différents ensembles filtrés du même tableau, est juste. Utilisez la méthode ci-dessous avec indexOf

8voto

Maxim Shoustin Points 20035

J'utiliserais le Underscore.js qui contient une liste de fonctions utiles.

without

without_.without(array, *values)

Renvoie une copie du tableau avec toutes les instances des valeurs supprimées.

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
// => [2, 3, 4]

Exemple

var res = "deleteMe";

$scope.nodes = [
  {
    name: "Node-1-1"
  },
  {
    name: "Node-1-2"
  },
  {
    name: "deleteMe"
  }
];

$scope.newNodes = _.without($scope.nodes, _.findWhere($scope.nodes, {
  name: res
}));

Voir la démo dans JSFiddle .


filter

var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });

// => [2, 4, 6]

Exemple

$scope.newNodes = _.filter($scope.nodes, function(node) {
  return !(node.name == res);
});

Voir la démo dans Violon .

0 votes

J'utiliserais probablement $scope.nodes = _.without($scope.nodes, node); parce qu'il fait référence à la node

0 votes

Sur les navigateurs modernes, vous pouvez utiliser Array.prototype.filter . _.filter(array, fun) devient array.filter(fun) .

7voto

cebor Points 2620
$scope.removeItem = function() {
    $scope.items.splice($scope.toRemove, 1);
    $scope.toRemove = null;
};

cela fonctionne pour moi !

4voto

Drako Points 38

Si vous avez une fonction associée à la liste, lorsque vous faites la fonction de jonction, l'association est également supprimée. 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 des paramètres est nommée articles . Le paramètre x.done indiquer si l'élément sera supprimé.

Une autre référence : Un autre exemple

J'espère vous aider. Salutations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X