wake-up-neo.com

Wie kann ich ein Objekt in einem Array ersetzen, das mit ng-repeat angezeigt wird?

Ich habe ein Array von Elementen, das in einer Tabelle mit ng-repeat angezeigt wird. Wenn Sie auf ein Element klicken, wird dieses Element vom Server abgerufen und die Tabelle sollte dann mit dem aktualisierten Element aktualisiert werden.

Funktion zum Abrufen des aktualisierten Elements beim Klicken auf ein Element in der Tabelle:

$scope.getUpdatedItem = function(item){
    itemService.getItem(item).then(
        function(updatedItem){
            item = updatedItem;
        },
        function(error){
            //Handle error
        }
    );
};

Ich zeige die Artikel mit:

<tr ng-repeat="item in myItems">

Das Problem: Das Element in der Tabelle wird nie aktualisiert.

Wie lässt sich der Artikel am besten in der Wiederholwiederholung aktualisieren? Kann ich dafür "track by $ index" im ng-repeat verwenden? Oder muss ich über myItems iterieren, um das Element zu finden, das ich ersetzen möchte?

Update:

Eine mögliche Lösung ist statt zu verwenden 

item = updatedItem,

benutzen:

var index = $scope.myItems.indexOf(item);
$scope.myItems[index] = updateItem;

Ich denke jedoch, dass es einen "saubereren" Weg geben sollte, dies zu tun.

15
gusper

Es gibt keinen saubereren Weg (dann Ihr Update). Wenn Sie item in Ihrer Rückruffunktion ändern, ändern Sie die lokale Referenz und nicht das ursprüngliche Element im Array.

Sie können dies etwas verbessern, indem Sie den $index aus dem ng-repeat verwenden, anstatt ihn selbst zu berechnen:

<div ng-click="getUpdatedItem(item, $index)"> </div>

Und in deinem Controller:

$scope.getUpdatedItem = function(item, index){
    itemService.getItem(item).then(
    function(updatedItem){
        $scope.myItems[index] = updateItem;
    },
    function(error){
        //Handle error
    }
    );
};

Sie können stattdessen auch angular.copy verwenden, aber es ist weniger effizient:

function(updatedItem){
    angular.copy(updateItem, item);
},
14
eladcon

Wenn ich dein Problem richtig verstehe

könnte so etwas funktionieren?

<!-- template code -->
<table>
    ...
    <tr ng-repeat="(index, item) in items">
        <td>{{item.name}}</td>
        <td>
             {{item.detail}}
             <button ng-if="!item.detail" ng-click="loadItem(index)">
        </td>
    </tr>
</table>

// Controller Code
$scope.items = [...]
$scope.loadItem = function(index){
    itemService.getItemDetail($scope.items[index]).then(function(itemDetail){
        $scope.items[index].detail = itemDetail;
    });
};
2
Eloims

item kann als Verweis auf ein Element in Ihrer Liste beginnen, wenn Sie jedoch Folgendes sagen:

item = updatedItem;

Sie setzen diese Bindung erneut ein - Sie beziehen sich nicht mehr auf den Eintrag in der Liste, sondern auf den nicht verbundenen, der in Ihrem Versprechen zurückgegeben wurde. Entweder müssen Sie das Element wie folgt ändern:

function(updatedItem){
  item.varA = updatedItem.varA
  item.varB = updatedItem.varB
  ...
}

Wenn es zu haarig wird, könnten Sie ein Element-Array in Betracht ziehen, das eher wie folgt aussieht:

var items = [ 
  { data: item1 },
  { data: item2 },
  { data: item3 }
};

An diesem Punkt sieht Ihre Aktualisierungsfunktion folgendermaßen aus:

function(updatedItem){
    item.data = updatedItem;
},
1
Michael Hays

Ich habe gerade Stunden damit verbracht. Ich konnte die $index-Lösung von @eladcon nicht verwenden, da mein ng-repeat auch einen Filter verwendet hat. Der Index ist nicht korrekt, wenn die Zeilen/Elemente gefiltert werden.

Ich dachte, ich könnte das einfach tun:

$filter('filter')($scope.rows, {id: 1})[0] = newItem;

aber das geht nicht.

Ich endete damit, das Array zu iterieren, bis ich eine Übereinstimmung gefunden hatte, und dann den $index aus der Iteration (nicht aus dem ng-repeat), um das Array-Element auf das neue Element festzulegen.

// i'm looking to replace/update where id = 1
angular.forEach($scope.rows, function(row, $index) {
  if (row.id === 1) {
    $scope.rows[$index] = newItem;
  }
})

Siehe hier: https://codepen.io/anon/pen/NpVwoq?editors=0011

0
Sean