反应形式 setValidator 和 updateOn

reactive forms setValidator and updateOn

我试图在 formControl 上动态设置验证器,但似乎无法使 updateOn: "blur" 正常工作。它似乎不是在模糊,而是在检查变化。我是否需要做一些特别的事情才能让它在模糊而不是变化上工作。

this.form.get("deviceInfo").controls.deviceNumber.setValidators({validators: [Validators.required, this.checkDeviceExists()], updateOn: 'blur'});

添加了 updateValueAndValidity() 但仍然会在发生变化而不是模糊时触发

var deviceInfo = this.form.get("deviceInfo");

deviceInfo.controls.deviceNumber.setValidators({validators: [Validators.required, this.checkDeviceExists()], updateOn: 'blur'});
deviceInfo.controls.deviceNumber.updateValueAndValidity();

显示动态验证的示例

this.form.get('company_name').setValidators(Validators.compose([Validators.required, Validators.maxLength(45)]));      


this.form.updateValueAndValidity();

https://medium.com/@theykillimmortal/dynamically-changing-of-angular-updateon-option-and-validation-behavior-7acc7f93f357

中描述了另一种技术

该方法是使用 setControl() 而不是 setValidators(),它允许构建整个控件(包括最重要的 AbstractControlOptionsupdateOn 属性).

例如

const oldControl = this.form.get('deviceInfo.deviceNumber');

const newControl = this.formBuilder.control(oldControl.value, { 
    validators: [Validators.required, this.checkDeviceExists()], 
    updateOn: 'blur' 
});

this.form.setControl('deviceInfo.deviceNumber', newControl);

这对我来说似乎太过分了,在我看来 setValidators() 应该允许传递 AbstractControlOptions 类型。

我有下面的独白:

请在为 FormBulder 创建 FormControl 时添加空验证器:

taxCode: [null, { validators: null, updateOn: 'blur' }]

然后添加新的验证器,条件为:

this.editForm.get('taxCode').setValidators(Validators.compose([isTaxcode]));
this.form.setControl('deviceInfo', 
   new FormControl(this.form.controls['deviceInfo'].value,
     {
      validators:[Validators.required,],
      updateOn: 'blur'
     })
 );

this.form.get('deviceInfo').updateValueAndValidity();

我很同情OP。我发现 Reactive form controls (v9) 在第一次被触摸时从不验证。如果我有一个当前有值的必填字段,并且用户单击该字段,删除该值,然后跳出,则不会应用无效样式元素(红色轮廓、图标等)。它们仅在提交时出现,或者如果用户碰巧单击返回字段然后再次退出。

这是我的方法,可以让验证在跳出以前从未接触过的无效字段时立即触发。

在我的控制器中(注意我在页面上有两个 Reactive 表单):

blurMe(e){
  let c = this.parentForm.controls[e.target.attributes['formControlName'].value];
  if(!c)
    c = this.childForm.controls[e.target.attributes['formControlName'].value];
  if(c){
    c.updateValueAndValidity({onlySelf:true,emitEvent:true});
  }
}

在我看来,我向任何需要立即验证的控件添加了一个简单的(模糊的)事件绑定。 (我使用的是 vmWare v3 的 Clarity 框架):

<input autocomplete="off" clrInput type="text" formControlName="badgeLabel" style="width:36em" (blur)="blurMe($event)" />