Angular 5 - Reactive表单在提交时不验证表单

时间:2017-12-11 08:11:51

标签: angular-reactive-forms angular5

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

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);
      }
    });
}

Reference

问题

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

1 个答案:

答案 0 :(得分:5)

在您的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属性中看到的DOM表单的提交(通过在表单中​​聚焦或点击表单的提交按钮时按ENTER键触发)将调用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表单验证