Disons que j'ai le tableau d'objets suivant, nommons-le itemArray;
{
"totalItems": 2,
"items": [
{
"id": 1,
"name": "foo"
},
{
"id": 2,
"name": "bar"
},
]
}
Et j’ai un abonnement qui renvoie le résultat mis à jour de l’id 2 uniquement. Comment puis-je mettre à jour le tableau d’objets sans effectuer de boucle dans tout le tableau?
Ce que j'aimerais, c'est quelque chose comme l'exemple ci-dessous;
updateUser(user){
this.myservice.getUpdate(user.id)
.subscribe(newitem => {
this.updateArray(newitem);
});
}
updateArray(newitem){
this.itemArray.items[newitem.id].name = newitem.name
}
ou même mieux, en remplaçant l'objet entier;
updateArray(newitem){
this.itemArray.items[newitem.id] = newitem
}
Cet exemple met toutefois à jour le tableau en fonction de l'index du tableau. Alors, comment puis-je mettre à jour à la place de newitem.id?
Modèle demandé en commentaire:
<tr *ngFor="let u of itemsArray.items; let i = index">
<td>{{ u.id }}</td>
<td>{{ u.name }}</td>
<td>
<input type="checkbox" checked="u.accepted" [(ngModel)]="itemsArray.items[i].accepted" (ngModelChange)="updateUser(u)">
<label for="singleCheckbox-{{i}}"></label>
</td>
</tr>
J'ai créé ce Plunker basé sur votre exemple qui met à jour l'objet égal à newItem.id
Voici l'extrait de mes fonctions:
showUpdatedItem(newItem){
let updateItem = this.itemArray.items.find(this.findIndexToUpdate, newItem.id);
let index = this.itemArray.items.indexOf(updateItem);
this.itemArray.items[index] = newItem;
}
findIndexToUpdate(newItem) {
return newItem.id === this;
}
J'espère que cela t'aides.
Mettre à jour directement l'élément passé en argument devrait faire l'affaire, mais il me manque peut-être quelque chose ici?
updateItem(item){
this.itemService.getUpdate(item.id)
.subscribe(updatedItem => {
item = updatedItem;
});
}
EDIT: Si vous n'avez vraiment pas d'autre choix que de parcourir tout votre tableau pour mettre à jour votre élément, utilisez findIndex:
let itemIndex = this.items.findIndex(item => item.id == retrievedItem.id);
this.items[itemIndex] = retrievedItem;
Vous pouvez aussi essayer ceci pour remplacer un objet existant
toDoTaskList = [
{id:'abcd', name:'test'},
{id:'abcdc', name:'test'},
{id:'abcdtr', name:'test'}
];
newRecordToUpdate = {id:'abcdc', name:'xyz'};
this.toDoTaskList.map((todo, i) => {
if (todo.id == newRecordToUpdate .id){
this.toDoTaskList[i] = updatedVal;
}
});
Une autre approche pourrait être:
let myList = [{id:'aaa1', name: 'aaa'}, {id:'bbb2', name: 'bbb'}, {id:'ccc3', name: 'ccc'}];
let itemUpdated = {id: 'aaa1', name: 'Another approach'};
myList.find(iitem => item.id == itemUpdated.id).name = itemUpdated.name;
Je créerais plutôt une carte
export class item{
name: string;
id: string
}
let caches = new Map<string, item>();
et alors vous pouvez simplement
this.caches[newitem.id] = newitem;
même
this.caches.set(newitem.id, newitem);
tableau est si 1999. :)
Vous pouvez utiliser la boucle for pour trouver votre élément et le mettre à jour:
updateItem(newItem){
for (let i = 0; i < this.itemsArray.length; i++) {
if(this.itemsArray[i].id == newItem.id){
this.users[i] = newItem;
}
}
}