我正在阅读this小文章。文章说:
If you need at some point to change the data in the collection, for example as a result of an API request, we have a problem because Angular can’t keep track of items in the collection and has no knowledge of which items have been removed or added.
As a result, Angular needs to remove all the DOM elements that associated with the data and create them again.
Note: when I’m saying “change the data” I’m referring to replace the collection with new objects and not keeping the same reference.
我试图检查是否如此。我的代码如下( stackblitz ):
html
<button (click)="changeObjItems()">Change Items array</button>
<app-item *ngFor="let i of objItems" [val]="i.item.id"></app-item>//line 2
typescript
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 仅销毁数据已更改的组件。但根据文章,我预计所有组件都会被销毁。
我在这里缺少什么?
最佳答案
您需要克隆数组中的所有对象来欺骗 ngFor 中的更改检测。
this.objItems[3] = {item:{id: Math.random()}};
this.objItems = this.objItems.map(obj => {...obj});
克隆/切片数组本身没有任何效果,因为 ngFor 正在针对每个 DOM 元素跟踪数组的内容。它会记住之前用于 DOM 元素的值,如果该值没有更改,则不会重新创建 DOM 元素。
对于发生变化但表示相同数据的项目来说,这可能是一个问题,这就是为什么 ngFor 具有 trackBy 回调,它允许您更改为 DOM 元素记住的值。
关于angular - *ngFor 没有按预期销毁组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53796195/