我正在阅读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仅破坏了已更改数据的组件。但是根据文章,我希望所有组件都被破坏。
我在这里想念什么?
答案 0 :(得分:2)
您需要克隆数组中的所有对象,以欺骗ngFor中的更改检测。
this.objItems[3] = {item:{id: Math.random()}};
this.objItems = this.objItems.map(obj => {...obj});
对数组本身进行克隆/切片没有任何作用,因为ngFor会针对每个DOM元素跟踪数组的内容。它会记住先前用于DOM元素的值,如果该值未更改,则不会重新创建DOM元素。
这对于突变但表示相同数据的项目可能是个问题,这就是ngFor具有trackBy回调的原因,该回调使您可以更改为DOM元素记住的值。