I have an array of items that is displayed in a table using ng-repeat. When you click on an item, that item is pulled from the server and the table should then be updated with the updated item.
Function to get the updated item when clicking on an item in the table:
$scope.getUpdatedItem = function(item){
itemService.getItem(item).then(
function(updatedItem){
item = updatedItem;
},
function(error){
//Handle error
}
);
};
I'm displaying the items using:
<tr ng-repeat="item in myItems">
The problem: The item in the table is never updated.
What's the best way to update the item in the ng-repeat? Can i use "track by $index" in the ng-repeat for this? Or do I have to iterate over myItems to find the item I want to replace?
Update:
A possible solution is instead of using
item = updatedItem,
to use:
var index = $scope.myItems.indexOf(item);
$scope.myItems[index] = updateItem;
However, I feel that there should be a "cleaner" way of doing this.
There isn't a much cleaner way (then your update).
As you noticed, when you change item
in your callback function you change the local reference, and not the original item in the array.
You can improve this a bit by using the $index
from the ng-repeat
, instead of calculating it yourself:
<div ng-click="getUpdatedItem(item, $index)"> </div>
And in your controller:
$scope.getUpdatedItem = function(item, index){
itemService.getItem(item).then(
function(updatedItem){
$scope.myItems[index] = updateItem;
},
function(error){
//Handle error
}
);
};
You can also use angular.copy
instead but it's much less efficient:
function(updatedItem){
angular.copy(updateItem, item);
},
If I understand your problem properly
could something like this work?
<!-- 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;
});
};
item
may start as a reference to an item in your list, but when you say:
item = updatedItem;
You reseat that binding -- you are no longer referring to the item in the list, but to the disconnected one that was returned in your promise. Either you will need to modify the item, like so:
function(updatedItem){
item.varA = updatedItem.varA
item.varB = updatedItem.varB
...
}
Or, if it gets too hairy, you might consider an item array that looks more like this:
var items = [
{ data: item1 },
{ data: item2 },
{ data: item3 }
};
At which point your update function will look like this:
function(updatedItem){
item.data = updatedItem;
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With