我有一个简单的表格如下:
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
后填写值,它也会返回 false
。但是,如果我在updateOn:'submit'
上删除了form
,那么它会在blur
输入控件上进行验证,并在输入值时验证表单返回true
。不确定updateOn
是否正常工作,或者我是否以适当的方式实施了此功能。有人能指出我正确的方向。
答案 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表单验证