wake-up-neo.com

Wie lösche ich ein Element oder ein Objekt aus einem Array mit ng-click?

Ich versuche, eine Funktion zu schreiben, die es mir ermöglicht, ein Element zu entfernen, wenn der Button angeklickt wird, aber ich denke, ich werde mit der Funktion verwirrt - benutze ich $digest?

HTML & 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

Um ein Element zu entfernen, müssen Sie es aus dem Array entfernen. Sie können das Element bday an Ihre remove-Funktion in markup übergeben. Suchen Sie dann im Controller den Index des Elements und entfernen Sie ihn aus dem Array

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

Dann im Controller:

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

Angular erkennt automatisch die Änderung des bdays-Arrays und führt die Aktualisierung von ng-repeat durch.

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

BEARBEITEN: Wenn Sie Live-Aktualisierungen mit dem Server durchführen, verwenden Sie einen Dienst, den Sie mit $resource erstellen, um die Array-Aktualisierungen zu dem Zeitpunkt zu verwalten, zu dem der Server aktualisiert wird

526
charlietfl

Dies ist eine korrekte Antwort: 

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

In @ charlietfl's Antwort. Ich denke, es ist falsch, da Sie $index als Parameter übergeben, aber Sie verwenden den Wunsch stattdessen im Controller. Korrigiere mich, wenn ich falsch liege :) 

50
nXqd

für den Fall, dass Sie sich in einer Wiederholung befinden

sie könnten eine Option für einen Liner verwenden

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

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

$index wird von angle verwendet, um den aktuellen Index des Arrays in einem ng-repeat anzuzeigen.

24
azerafati

Die Verwendung von $index funktioniert in einfachen Fällen perfekt und die Antwort von @ charlietfl ist großartig. Manchmal reicht $index jedoch nicht aus. 

Stellen Sie sich vor, Sie haben ein einzelnes Array, das Sie in zwei verschiedenen Wiederholungen präsentieren. Eine dieser Wiederholungen wird nach Objekten gefiltert, die über eine wahrheitsgemäße Eigenschaft verfügen, und die andere nach einer falschen Eigenschaft. Es werden zwei verschiedene gefilterte Arrays vorgestellt, die von einem einzigen Originalarray stammen. (Oder wenn es hilfreich ist zu visualisieren: Vielleicht haben Sie ein einzelnes Array von Leuten, und Sie möchten eine Wiederholung für die Frauen in diesem Array und ein anderes für die Männer in demselben Array .) Ihr Ziel: zuverlässig aus dem ursprünglichen Array löschen, unter Verwendung der Informationen der Mitglieder der gefilterten Arrays. 

In jedem dieser gefilterten Arrays ist $ index nicht der Index des Elements innerhalb des ursprünglichen Arrays. Es wird der Index im gefilterten Subarray sein. Sie können also den Index der Person nicht im ursprünglichen people-Array angeben, Sie kennen den $ -Index nur vom women- oder men-Subarray. Versuchen Sie, das zu löschen, und Elemente werden überall verschwinden, außer wo Sie möchten. Was ist zu tun?

Wenn Sie Glück haben, dass ein Datenmodell einen eindeutigen Bezeichner für jedes Objekt enthält, verwenden Sie diesen anstelle von $ index, um das Objekt und splice aus dem Hauptarray herauszufinden. (Verwenden Sie mein Beispiel, aber mit dieser eindeutigen Kennung.) Aber wenn Sie nicht so viel Glück haben? 

Angular erweitert jedes Element in einem wiederholten ng-Array (im ursprünglichen Originalarray) um die einzigartige Eigenschaft $$hashKey. Sie können das ursprüngliche Array nach dem $$hashKey des Elements, das Sie löschen möchten, nach einer Übereinstimmung durchsuchen und es auf diese Weise entfernen.

Beachten Sie, dass $$hashKey ein Implementierungsdetail ist, das nicht in der veröffentlichten API für ng-repeat enthalten ist. Sie könnten die Unterstützung für diese Eigenschaft jederzeit entfernen. Aber wahrscheinlich nicht. :-)

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

Aufruf mit:

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

BEARBEITEN: Wenn Sie eine Funktion wie diese verwenden, die anstelle eines modellspezifischen Eigenschaftennamens auf dem $$hashKey Schlüssel verwendet, hat dies auch den erheblichen zusätzlichen Vorteil, dass diese Funktion in verschiedenen Modellen und Kontexten wiederverwendbar ist. Geben Sie Ihre Array-Referenz und Ihre Artikel-Referenz an, und es sollte funktionieren.

22
XML

Ich schreibe normalerweise in einem solchen Stil:

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


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

Hoffen Sie, dass dies hilft.

Aufbauend auf der akzeptierten Antwort funktioniert dies mit ngRepeat, filterund behandelt Erwartungen besser

Controller:

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

Aussicht:

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

Ich stimme nicht zu, dass Sie eine Methode auf Ihrem Controller aufrufen sollten. Sie sollten einen Dienst für jede tatsächliche Funktionalität verwenden, und Sie sollten Richtlinien für alle Funktionen für Skalierbarkeit und Modularität definieren sowie ein Klickereignis zuweisen, das einen Aufruf an den Dienst enthält, den Sie in Ihre Anweisung einfügen. 

So zum Beispiel in Ihrem HTML ...

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

Dann erstellen Sie eine Direktive ...

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

Dann in Ihrem Dienst ...

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

Wenn Sie Ihren Code auf diese Weise richtig schreiben, können Sie zukünftige Änderungen sehr einfach schreiben, ohne Ihren Code umstrukturieren zu müssen. Es ist ordnungsgemäß organisiert und Sie verarbeiten benutzerdefinierte Klickereignisse korrekt, indem Sie sie mit benutzerdefinierten Anweisungen binden. 

Wenn Ihr Client beispielsweise sagt: "Hey, jetzt lassen Sie uns den Server anrufen, Brot machen und dann eine Modalität anzeigen." Sie können einfach zum Dienst selbst gehen, ohne HTML-Code und/oder Controller-Methodencode hinzufügen oder ändern zu müssen. Wenn Sie nur eine einzige Zeile auf dem Controller hätten, müssten Sie eventuell einen Dienst verwenden, um die Funktionalität auf das schwerere Heben auszuweiten, das der Client anfordert. 

Wenn Sie an einer anderen Stelle eine andere 'Löschen'-Schaltfläche benötigen, haben Sie jetzt ein Direktive-Attribut (' ng-remove-birthday '), das Sie problemlos jedem Element auf der Seite zuweisen können. Dies macht es jetzt modular und wiederverwendbar. Dies wird sich als nützlich erweisen, wenn Sie sich mit dem HEAVY-Webkomponenten-Paradigma von Angular 2.0 beschäftigen. Dort IS kein Controller in 2.0. :)

Viel Spaß beim Entwickeln !!!

3
Justin Russo

implementierung ohne Controller.

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

Die splice () -Methode fügt Elemente zu/aus einem Array hinzu.

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

index : Erforderlich. Eine Ganzzahl, die angibt, an welcher Position Elemente hinzugefügt/entfernt werden sollen. Verwenden Sie negative Werte, um die Position am Ende des Arrays anzugeben.

howmanyitem (s) : Optional. Die Anzahl der Elemente, die entfernt werden sollen. Bei der Einstellung 0 werden keine Elemente entfernt.

item_1, ..., item_n : Optional. Die neuen Elemente, die dem Array hinzugefügt werden sollen

2
Deepu Reghunath

Hier ist eine andere Antwort. Ich hoffe es wird helfen.

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

Vollständige Quelle ist hier
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

1

wenn Sie eine ID oder ein bestimmtes Feld in Ihrem Artikel haben, können Sie filter () verwenden. Es ist wie Wo ().

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

im Controller:

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

von der Steuerung (Funktion kann in der gleichen Steuerung sein, aber es vorziehen, sie in einem Dienst zu halten)

    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