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 表单验证。
我有一个简单的表格如下:
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 表单验证。