对象数组中的角度更新对象

时间:2017-05-22 19:23:13

标签: angular typescript

假设我有以下对象数组,请将其命名为itemArray;

{
  "totalItems": 2,
  "items": [
    {
      "id": 1,
      "name": "foo"

    },
    {
      "id": 2,
      "name": "bar"
    },
    ]
}

我有一个订阅,只返回id 2的更新结果。如何在不循环整个数组的情况下更新对象数组?

我想要的是类似下面的例子;

updateUser(user){
    this.myservice.getUpdate(user.id)
    .subscribe(newitem => {
      this.updateArray(newitem);
    });
}

  updateArray(newitem){
    this.itemArray.items[newitem.id].name = newitem.name
  }

甚至更好,替换整个对象;

  updateArray(newitem){
    this.itemArray.items[newitem.id] = newitem
  }

但是,此示例根据数组的索引更新数组。那么我如何根据newitem.id更新?

评论中要求的模板:

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

9 个答案:

答案 0 :(得分:43)

我已根据您的示例创建此Plunker,该对象更新了等于newItem.id的对象

这是我的功能片段:

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

希望这有帮助。

答案 1 :(得分:19)

直接更新作为参数传递的项目应该完成这项工作,但我可能在这里遗漏了一些东西?

updateItem(item){
  this.itemService.getUpdate(item.id)
  .subscribe(updatedItem => {
    item = updatedItem;
  });
}

编辑:如果你真的别无选择,只能遍历整个数组来更新你的项目,请使用findIndex:

let itemIndex = this.items.findIndex(item => item.id == retrievedItem.id);
this.items[itemIndex] = retrievedItem;

答案 2 :(得分:8)

另一种方法可能是:

let myList = [{id:'aaa1', name: 'aaa'}, {id:'bbb2', name: 'bbb'}, {id:'ccc3', name: 'ccc'}];
let itemUpdated = {id: 'aaa1', name: 'Another approach'};

myList.find(item => item.id == itemUpdated.id).name = itemUpdated.name;

// item而不是iitem

答案 3 :(得分:5)

您也可以尝试替换现有对象

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

答案 4 :(得分:3)

我宁愿创建地图

export class item{
    name: string; 
    id: string
}

let caches = new Map<string, item>();

然后你可以简单地

this.caches[newitem.id] = newitem; 

甚至

this.caches.set(newitem.id, newitem); 

数组是如此1999. :)

答案 5 :(得分:0)

您可以使用for循环来查找元素并进行更新:

col1  col2
 a     0
 b     1
 c     0
 d     0
 c     0
 d     0

答案 6 :(得分:0)

在angular / typescript中,我们可以避免数组中的对象发生突变。

使用项目arr作为BehaviorSubject的示例:

// you can initialize the items$ with the default array
this.items$ = new BehaviorSubject<any>([user1, user2, ...])

updateUser(user){
   this.myservice.getUpdate(user.id).subscribe(newitem => {

     // remove old item
     const items = this.items$.value.filter((item) => item.id !== newitem.id);

     // add a the newItem and broadcast a new table
     this.items$.next([...items, newItem])
   });
}

在模板中,您可以订阅项目$

<tr *ngFor="let u of items$ | async; let i = index">
   <td>{{ u.id }}</td>
   <td>{{ u.name }}</td>
   <td>
        <input type="checkbox" checked="u.accepted" (click)="updateUser(u)">
        <label for="singleCheckbox-{{i}}"></label>
   </td>
</tr>

答案 7 :(得分:0)

updateValue(data){    
     // retriving index from array
     let indexValue = this.items.indexOf(data);
    // changing specific element in array
     this.items[indexValue].isShow =  !this.items[indexValue].isShow;
}

答案 8 :(得分:0)

试试 Array.ForEach() 方法。

   itemArray.ForEach(item =>{
         if(item.id == newitem.id){
            item.name = newitem.name
         }
      });