有没有办法等待Angular中的DOM更新?

时间:2019-12-03 01:52:30

标签: angular angular-forms

如果我有以下类似内容

<form #myForm="ngForm">
  <input *ngFor="let item of items; index as i" [name]="'input_' + i" [(ngModel)]="item" myValidationAttribute>
</form>

我有一个更新项目的功能,我需要等待表单更新后再提交表单

updateAndSubmit() {
  this.items = newItems;
  setTimeout(() => {
    if (this.myForm.valid) {
      // Do stuff with valid form
    }
  });
}

像这样使用setTimeout是等待DOM刷新的首选方法,还是在单元测试中使用了fix.whenStable()方法?

setTimeout感觉不对,就像是一个肮脏的黑客一样。

这是一个StackBlitz https://stackblitz.com/edit/angular-pv4tyb

2 个答案:

答案 0 :(得分:1)

正如@Antediluvian所说,这不是hack,它是关于将回调放置在事件队列的末尾,即确保回调中的代码不在当前事件循环中运行,而是在下一个事件循环中运行。一个或以后。

也就是说,如果您发现自己做了类似的事情,并且需要在setTimeout中指定延迟,那么您就遇到了问题,因为开发中使用的延迟不太可能对所有客户端都有效。

在这种情况下,您使用的简单setTimeout应该很好,并且AFAIK是“完成的方式”。

我了解您的实际代码更加复杂,但是基于此示例,请考虑您不需要通过表单推送该额外的值-您只需获取表单的值,然后直接对其进行修改(或表单值的副本)以产生您使用的值(例如,发布到API)。

答案 1 :(得分:0)

对我来说,这是100%的反应形式用例,而不是模板驱动形式:

<form [formGroup]="itemsFa">
  <input *ngFor="let item of itemsFa.controls; index as i" [name]="'input_' + i" [formControlName]="i">
</form>


constructor(private fb: FormBuilder) {
  this.itemsFa = this.fb.array([]);
}

updateAndSubmit() {
  this.itemsFa.clear();
  newItems.forEach(item => {
    const fc = new FormControl(item, [myValidator]); // convert validation directive to validator fn
    this.itemsFa.push(fc)
  });
  if (this.itemsFa.valid) {
    // Do stuff with valid form
  }
}

闪电战示例:https://stackblitz.com/edit/angular-h5rhgx?file=src%2Fapp%2Fapp.module.ts