更改检测未注册数据更改

m41*_*41n 7 angular-http angular

我有一个html结构,组件内部有一个组件(忘记了正确的单词).

基本上像这样工作(很大程度上简化):

主要的HTML:

<div *ngFor="let item of data">
  <app-item [item]="item"></app-item>
</div>

<button (click)="addItem()">Add</button>
Run Code Online (Sandbox Code Playgroud)

item html:

<div>{{item.name}}</div>

<button (click)="deleteItem()">Delete</button>
Run Code Online (Sandbox Code Playgroud)

在app-item中我从列表中显示了几个项目.该列表通过http.get请求将数据直接从数据库中获取.

现在我还有添加或删除两个工作项的功能(项目分别添加到数据库或从数据库中删除项目就好了).虽然更改检测不会选择其中任何一个并且需要刷新站点(例如通过F5)来显示更改.

我检查了代码(并非所有代码都来自我)并且找不到任何指定的更改检测策略.

我还尝试通过ChangeDetectorRef(this.ref.detectChanges();)从添加和删除功能手动触发更改检测.虽然这也没有消除手动刷新页面以查看更改的需要.

现在我发现变量检测缺少什么呢?或者,我如何在添加/删除方法中手动触发它?

Pra*_*ali 9

由于您在现有数组中添加或删除元素,因此无法选择更改.

为此,你可以这样做

  • 使用与数组相同元素的新对象分配数组引用 items= items.slice();
  • 或者您可以使用Object.assign方法作为items= Object.assign([],items);
  • 在对数组进行更改后,应该完成这两件事.

要手动触发变更检测,您可以按照以下链接回答: -

ChangeDetectorRef在组件中注入,然后使用detectChanges()该对象的方法手动触发更改检测.喜欢

constructure(private cd: ChangeDetectorRef) {}

someMethod() {
    this.cd.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)

  • 我真的不明白,如果当你设置一个真正简单的启动项目并更改和数组时,视图会发生变化......直到项目增长并且它不再工作......这真的很奇怪和不透明。检测数组更改应该是 ng 中的本机 (4认同)
  • ChangeDetectorRef 的第二个选项,我实际上尝试过。虽然没有带来想要的结果 (2认同)
  • 在 3 种方式中,只有 ChangeDetectorRef 对我有用。+1 (2认同)

cpi*_*cpi 9

如果您使用扩展运算符而不是推送它应该可以工作。

this.data = [...this.data, newItem];
Run Code Online (Sandbox Code Playgroud)

这样做的原因是当整个对象发生变化或引用发生变化时,angular 会检测到变化,因此突变不会触发它。因此,与其改变数组,不如让它成为一个新数组。