添加新元素时,角度更新现有 FormArray 元素的有效性

Posted

技术标签:

【中文标题】添加新元素时,角度更新现有 FormArray 元素的有效性【英文标题】:Angular updates validity of existing FormArray elements when new element is added 【发布时间】:2018-12-11 18:28:03 【问题描述】:

我不想要这个。因为我正在异步验证FormArray 的每个元素,所以我希望验证器仅在必要时运行(即,当它们添加到的控件的值真正改变时)。我也觉得这种行为很奇怪,因为当FormArray 的值发生变化时,验证器不会被执行,只有在添加新元素时才会执行。

复制:https://stackblitz.com/edit/angular-reactive-forms-tkdu1n?file=app%2Fapp.component.ts

任何帮助将不胜感激

【问题讨论】:

【参考方案1】:

当一个新的FormControl 被推入其中时,FormArray 似乎为每个嵌套的FormControl 执行验证器,并且对此无能为力...

所以我分叉了你的 stackblitz,并创建了一个带有闭包的有状态验证器,它成功了:

form: FormArray;

ngOnInit() 
  this.form = new FormArray([]);
  this.form.push(new FormControl("test", null, this.validatorFactory()));


addControl() 
  this.form.push(new FormControl(null, null, this.validatorFactory()));


validatorFactory() 
  let previousValue;
  return (c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => 
    if (c.value == previousValue) 
      return Observable.of(null);
     else 
      previousValue = c.value;
      return Observable.of(null).delay(1000);
    
  ;

Forked Stackblitz

希望这会有所帮助!

【讨论】:

【参考方案2】:

是的,只需更改

return Observable.of(null).delay(1000);

return Observable.of(null).delay(0);

当您将延迟设为 1000 毫秒时,您还会禁用并阻止其他实例(或值)状态的可访问性,但是,当您将延迟设为 0 时,它不会处理其他实例,只会检查当前实例。

希望对您有所帮助!

【讨论】:

在使用真实服务而不是模拟服务时,我无法设置延迟... 显然它仍在为每个控件调用验证器,只是延迟消失了。 当然,您无法摆脱这一点,因为您为它们使用了单个验证器,但鉴于消除延迟时它不会像那样行事。如果你想避免它,你应该为每个值使用新的 FormArray 实例,这当然是个糟糕的主意。我认为最好的方法是自己进行验证,而不是使用 FormArray。

以上是关于添加新元素时,角度更新现有 FormArray 元素的有效性的主要内容,如果未能解决你的问题,请参考以下文章

更新 formArray 值 angular form 时,Form 不断重新渲染

Boto3 S3 更新现有对象的元数据

剑道:将顶部的 FormGroup 插入 FormArray

Angular Cdk步进器,如何检测何时添加了新步骤

如何以角度在 FormArray 中设置值?

无法根据角度formarray下拉选择显示/隐藏div [关闭]