* ngFor没有破坏预期的组件

时间:2018-12-15 18:43:58

标签: angular

我正在阅读this小文章。文章说:

  

如果您需要在某个时候更改集合中的数据(例如,由于API请求),我们会遇到问题,因为Angular无法跟踪集合中的项目并且不知道哪些项目已被删除或添加。

     

结果, Angular需要删除与数据关联的所有DOM元素,然后再次创建它们。

     

注意:当我说“更改数据”时,是指用新对象替换集合,而不保留相同的引用。

我试图检查是否。我的代码如下(stackblitz):

html

 <button (click)="changeObjItems()">Change Items array</button>
 <app-item *ngFor="let i of objItems" [val]="i.item.id"></app-item>//line 2

打字稿

   objItems = [
      {item: {id:1}},
      {item: {id:1}},
      {item: {id:1}},
      {item: {id:1}}
    ];

  changeObjItems(){
     this.objItems[3] = {item:{id: Math.random()}};
     this.objItems = [...this.objItems];//shallow clone
  }

因此基本上在第2行中,我遍历数组嵌套对象(objItems),并在每次迭代时创建一个新组件(app-item)。稍后,我要更改数组的数据(通过changeObjItems(),并通过登录app-item的onDestroy来检查是否破坏了所有先前的组件。

但是,在运行changeObjItems()之后,控制台显示* ngFor仅破坏了已更改数据的组件。但是根据文章,我希望所有组件都被破坏。

enter image description here

我在这里想念什么?

1 个答案:

答案 0 :(得分:2)

您需要克隆数组中的所有对象,以欺骗ngFor中的更改检测。

 this.objItems[3] = {item:{id: Math.random()}};
 this.objItems = this.objItems.map(obj => {...obj});

对数组本身进行克隆/切片没有任何作用,因为ngFor会针对每个DOM元素跟踪数组的内容。它会记住先前用于DOM元素的值,如果该值未更改,则不会重新创建DOM元素。

这对于突变但表示相同数据的项目可能是个问题,这就是ngFor具有trackBy回调的原因,该回调使您可以更改为DOM元素记住的值。