首页 文章

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

提问于
浏览
2

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

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

参考


问题

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

1 回答

  • 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'
    })
    

    正如我们在主办属性中看到的 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 表单验证。

相关问题