Angular 5 - 响应式表单在提交时不验证表单

Angular 5 - Reactive forms doesn't validate form on submit

我有一个简单的表格如下:

some.component.html

<form class="example-form" novalidate (ngSubmit)="onSubmit()" autocomplete="off" [formGroup]="testform">
     <input type="text" formControlName="name" class="form-control" placeholder="Enter name" required/>
     <app-show-errors [control]="claimform.controls.name"></app-show-errors>
     <button type="submit" (click)="onSubmit()">Next</button>
</form>

some.component.ts

ngOnInit() {
    this.testform= new FormGroup({
      name: new FormControl('', { validators: Validators.required})
    }, {updateOn: 'submit'});
}

onSubmit() {
    if (this.testform.valid) {
      alert('saving data');
    } else {
      this._validationService.validateAllFormFields(this.testform);
    }
}

validationService.ts

validateAllFormFields(formGroup: FormGroup) {
    Object.keys(formGroup.controls).forEach(field => {
      const control = formGroup.get(field);
      if (control instanceof FormControl) {
        control.markAsTouched({ onlySelf: true });
      } else if (control instanceof FormGroup) {
        this.validateAllFormFields(control);
      }
    });
}


问题

如果留空,表格将 validate on submit,但即使在我检查 this.testform.valid 时填写值后 returns false。但是,如果我在 form 上删除 updateOn:'submit',那么它会在输入控件的 blur 上进行验证,当输入值时,它会在 return true 上进行验证。不确定 updateOn 是否工作正常,或者我是否以正确的方式实现了它。有人能给我指出正确的方向吗?

在您的 HTML 中,您有两次调用 onSubmit() 函数,来自提交按钮:

<button type="submit" (click)="onSubmit()">Next</button>

并从表格:

<form class="example-form" 
      ovalidate 
      (ngSubmit)="onSubmit()" 
      autocomplete="off" 
      [formGroup]="testform">

第一个被触发的调用是按钮的触发器,它实际上在更新您的反应形式方面没有做任何事情,因为您将 FormGroup 的选项设置为 {updateOn: 'submit'}。要触发的第二个调用是表单的触发器,它执行实际的表单更新。

这里是FormGroup指令配置:

@Directive({
  selector: '[formGroup]',
  providers: [formDirectiveProvider],
  host: {'(submit)': 'onSubmit($event)', '(reset)': 'onReset()'},
  exportAs: 'ngForm'
})

正如我们在 host property DOM form's submit (triggered by hitting ENTER while focused within form or clicking form's submit button) will call onSubmit() 函数中看到的:

onSubmit($event: Event): boolean {
  (this as{submitted: boolean}).submitted = true;
  syncPendingControls(this.form, this.directives);
  this.ngSubmit.emit($event);
  return false;
}

然后将调用 syncPendingControls() 函数:

export function syncPendingControls(form: FormGroup, directives: NgControl[]): void {
  form._syncPendingControls();
  directives.forEach(dir => {
    const control = dir.control as FormControl;
    if (control.updateOn === 'submit' && control._pendingChange) {
      dir.viewToModelUpdate(control._pendingValue);
      control._pendingChange = false;
    }
  });
}

最后更新模型

因此,在您的情况下,只需从提交按钮中删除 (click)="onSubmit()"

<button type="submit">Next</button>

你的输入也不需要 required DOM 元素 属性 ,因为你使用 Reactive Forms API validators: Validators.required 设置了它并且你将您的表单设置为 novalidate,这会取消 HTML5 表单验证。