web-dev-qa-db-fra.com

Comment puis-je supprimer un élément ou un objet d'un tableau en utilisant ng-click?

J'essaie d'écrire une fonction qui me permet de supprimer un élément lorsque l'utilisateur clique sur le bouton, mais je pense que je suis confus avec la fonction. Est-ce que j'utilise $digest?

HTML et 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();
};
248
Jess McKenzie

Pour supprimer un élément, vous devez le supprimer du tableau et vous pouvez transmettre un élément bday à votre fonction de suppression dans le balisage. Puis, dans le contrôleur, recherchez l’index de l’article et retirez-le du tableau.

<a class="btn" ng-click="remove(item)">Delete</a>

Puis dans le contrôleur:

$scope.remove = function(item) { 
  var index = $scope.bdays.indexOf(item);
  $scope.bdays.splice(index, 1);     
}

Angular détectera automatiquement la modification apportée au tableau bdays et effectuera la mise à jour de ng-repeat

DEMO: http://plnkr.co/edit/ZdShIA?p=preview

EDIT: si les mises à jour en direct avec le serveur utilisent un service que vous créez à l'aide de $resource pour gérer les mises à jour du tableau en même temps que le serveur

526
charlietfl

C'est une réponse correcte: 

<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove=function($index){ 
  $scope.bdays.splice($index,1);     
}

Dans la réponse de @ charlietfl. Je pense que c'est faux puisque vous passez $index en tant que paramètre mais que vous utilisez le souhait à la place du contrôleur. Corrige moi si je me trompe :) 

50
nXqd

au cas où vous êtes à l'intérieur d'un ng-repeat

vous pouvez utiliser une option one liner

    <div ng-repeat="key in keywords"> 
        <button ng-click="keywords.splice($index, 1)">

            {{key.name}}
        </button>
    </div>

$index est utilisé par angular pour afficher l'index actuel du tableau dans un ng-repeat

24
azerafati

Utiliser $index fonctionne parfaitement dans les cas simples, et la réponse de @ charlietfl est excellente. Mais parfois, $index ne suffit pas. 

Imaginez que vous ayez un seul tableau, que vous présentez dans deux ng-repeat différents. Un de ces ng-repeat est filtré pour les objets qui ont une propriété de vérité, et l'autre est filtré pour une propriété de faux. Deux tableaux filtrés différents sont présentés, qui proviennent d'un seul tableau d'origine. (Ou, si cela aide de visualiser: peut-être que vous avez un seul tableau de personnes et que vous voulez un ng-repeat pour les femmes de ce tableau et un autre pour les hommes de le même tableau.) Votre objectif: supprimer de manière fiable le tableau d'origine, en utilisant les informations des membres des tableaux filtrés. 

Dans chacun de ces tableaux filtrés, $ index ne sera pas l'index de l'élément dans le tableau d'origine. Ce sera l'index dans le sous-tableau filtré. Ainsi, vous ne pourrez pas indiquer l'index de la personne dans le tableau people d'origine, vous ne connaîtrez que l'index $ du sous-tableau women ou men. Essayez de supprimer en utilisant cela, et vous aurez des éléments qui disparaissent de partout, sauf où vous voulez. Que faire?

Si vous avez la chance d'utiliser un modèle de données incluant un identifiant unique pour chaque objet, utilisez-le plutôt que $ index pour rechercher l'objet et splice dans le tableau principal. (Utilisez mon exemple ci-dessous, mais avec cet identifiant unique.) Mais si vous n'êtes pas aussi chanceux? 

Angular ajoute en réalité chaque élément d’un tableau répété ng (dans le tableau principal principal) à une propriété unique appelée $$hashKey. Vous pouvez rechercher dans le tableau d'origine une correspondance sur le $$hashKey de l'élément que vous souhaitez supprimer, et vous en débarrasser ainsi.

Notez que $$hashKey est un détail d'implémentation, non inclus dans l'API publiée pour ng-repeat. Ils pourraient supprimer le support de cette propriété à tout moment. Mais probablement pas. :-)

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

Invoquer avec:

ng-click="deleteFilteredItem(item.$$hashKey, refToSourceArray)"

ÉDITER: l’utilisation d’une fonction comme celle-ci, qui utilise le $$hashKey au lieu d’un nom de propriété spécifique au modèle, présente également l’avantage supplémentaire de rendre cette fonction réutilisable dans différents modèles et contextes. Fournissez-le avec votre référence de tableau, et votre référence d'élément, et cela devrait fonctionner.

22
XML

J'écris d'habitude dans un tel style:

<a class="btn" ng-click="remove($index)">Delete</a>


$scope.remove = function(index){
  $scope.[yourArray].splice(index, 1)
};

J'espère que cela vous aidera. Vous devez utiliser un point (.) Entre $ scope et [yourArray]

8

Sur la base de la réponse acceptée, cela fonctionnera avec ngRepeat, filteret gérera mieux les expections:

Manette:

vm.remove = function(item, array) {
  var index = array.indexOf(item);
  if(index>=0)
    array.splice(index, 1);
}

Vue:

ng-click="vm.remove(item,$scope.bdays)"
8

Je ne suis pas d'accord pour dire que vous devriez appeler une méthode sur votre contrôleur. Vous devez utiliser un service pour toute fonctionnalité réelle et définir des directives pour toute fonctionnalité d'évolutivité et de modularité, ainsi que pour affecter un événement click contenant un appel au service que vous injectez dans votre directive. 

Donc, par exemple, sur votre code HTML ...

<a class="btn" ng-remove-birthday="$index">Delete</a>

Ensuite, créez une directive ...

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

Alors à votre service ...

angular.module('myApp').factory('myService', [function(){
    return {
        removeBirthday: function(birthdayIndex, scope){
            scope.bdays.splice(birthdayIndex);
            scope.$apply();
        }
    };
}]);

Lorsque vous écrivez votre code correctement de cette manière, vous faciliterez considérablement l’écriture des modifications futures sans avoir à restructurer votre code. Il est organisé correctement et vous gérez correctement les événements de clic personnalisés en les liant à l'aide de directives personnalisées. 

Par exemple, si votre client dit: "Hé, maintenant, appelons le serveur et faisons du pain, puis affichez un modal." Vous pourrez facilement accéder au service lui-même sans avoir à ajouter ou à modifier le code HTML et/ou le code de la méthode du contrôleur. Si vous n'aviez qu'une ligne sur le contrôleur, vous auriez éventuellement besoin d'un service, pour étendre la fonctionnalité au levage plus lourd demandé par le client. 

De plus, si vous avez besoin d'un autre bouton "Supprimer" ailleurs, vous disposez maintenant d'un attribut de directive ("ng-remove-birthday") que vous pouvez facilement affecter à n'importe quel élément de la page. Cela le rend maintenant modulaire et réutilisable. Cela s’avérera utile lorsqu’il s’agit du paradigme HEAVY des composants Web de Angular 2.0. Il n'y a IS pas de contrôleur en 2.0. :)

Bon développement !!!

3
Justin Russo

mise en œuvre sans contrôleur.

<!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">{{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>

La méthode splice () ajoute/supprime des éléments dans/depuis un tableau.

array.splice(index, howmanyitem(s), item_1, ....., item_n)

index : Obligatoire. Un entier spécifiant à quelle position ajouter/supprimer des éléments, utilisez des valeurs négatives pour spécifier la position à partir de la fin du tableau.

howmanyitem (s) : Facultatif. Le nombre d'éléments à supprimer. Si défini sur 0, aucun élément ne sera supprimé.

item_1, ..., item_n : Facultatif. Le ou les nouveaux éléments à ajouter au tableau

2
Deepu Reghunath

Voici une autre réponse. J'espère que cela aidera.

<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, ...)

La source complète est ici
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

1
Bahodir Boydedayev

si vous avez un identifiant ou un champ spécifique dans votre article, vous pouvez utiliser filter (). son acte comme Where ().

<a class="btn" ng-click="remove(item)">Delete</a>

dans le contrôleur:

$scope.remove = function(item) { 
  $scope.bdays = $scope.bdays.filter(function (element) {
                    return element.ID!=item.ID
                });
}
0
Pass the id that you want to remove from the array to the given function 

depuis le contrôleur (la fonction peut être dans le même contrôleur mais préfère le garder dans un service)

    function removeInfo(id) {
    let item = bdays.filter(function(item) {
      return bdays.id=== id;
    })[0];
    let index = bdays.indexOf(item);
    data.device.splice(indexOfTabDetails, 1);
  }
0
Utkarsh Joshi