Angular2:*ngFor在更新数组时不更新

Rol*_*ácz 16 angular2-changedetection angular

我有一个对象数组(让我们称之为arr).在方法的一个组件输入中,(change)我修改了这些对象的属性之一,但在视图(*ngFor)中没有任何变化.我读到Angular2变化检测不检查数组或对象的内容,所以我尝试了这些:

this.arr = this.arr.slice();
Run Code Online (Sandbox Code Playgroud)

和

this.arr = [...this.arr];
Run Code Online (Sandbox Code Playgroud)

但是视图没有改变,它仍然显示旧的属性.在(change)方法中console.log()我得到了正确的数组.奇怪,但是这一个工程:this.arr = []; 我想NgZone和markForCheck()太.

Wil*_*ire 20

既然你提到你已经尝试过markForCheck(),你应该试试 detectChanges (这对我有用,而 markForCheck 不起作用)。对于那些需要步骤的人:

将 ChangeDetectorRef 添加到您的导入中:

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
Run Code Online (Sandbox Code Playgroud)

将 ChangeDetectorRef 添加到您的构造函数中:

constructor(
    private changeDetection: ChangeDetectorRef
  ) { }
Run Code Online (Sandbox Code Playgroud)

然后在更新数组后的下一行:

this.changeDetection.detectChanges();
Run Code Online (Sandbox Code Playgroud)

  • 如果 trackby 没有检测到数组的变化,请使用这个示例并享受它。 (3认同)

Mic*_*ouw 7

您也trackBy可以在*ngFor表达式中使用该选项,为数组中的每个项目提供唯一的ID。这确实使您100%负责更改检测,因此每次数组中的项目更改时都要更新此(唯一)属性。然后,只有在数组中的任何项目都被赋予了不同的trackBy属性时,Angular才会重新渲染列表:

*ngFor="let item of (itemList$ | async); trackBy: trackItem"

要么:

*ngFor="let item of itemList; trackBy: trackItem"

哪里:

trackItem 是组件中的公共方法:

public trackItem (index: number, item: Item) {
  return item.trackId;
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案 (2认同)

cup*_*_of 7

游戏迟到了,但使用 lodash 创建深度克隆对我来说很有效

this.arr = cloneDeep(this.arr);

https://lodash.com/docs/4.17.15#cloneDeep

  • 为此不需要低破折号。`this.arr = this.arr.map(el => Object.assign({}, el)` 或 `this.arr = [...this.arr]` 它是一个基元数组。 (2认同)