angular - *ngFor 没有按预期销毁组件

标签 angular

我正在阅读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 仅销毁数据已更改的组件。但根据文章,我预计所有组件都会被销毁。

enter image description here

我在这里缺少什么?

最佳答案

您需要克隆数组中的所有对象来欺骗 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/

相关文章:

angular - 如何为 Angular 6 应用程序启用 CSS 源映射?

angular - 以 Angular 2 动态呈现 HTML

json - Angular 2 应用程序部署到 Azure 时出现错误 404

angular - JHipster非 Angular 登录页面

Angular 2 - 如何上传文件并存储在本地文件夹中

javascript - Angular2 - 登录后重定向

angular - 如何从 `.d.ts` 文件导入?

Angular Element 不解析另一个 Angular 项目中的路由(?),网站上只显示 "<router-outlet></router-outlet>"

css - 无法获取 :before element to appear on ReactiveForms input

angular - 如何覆盖 Angular 5 中的组件?