使用ControlValueAccessor for SubForm的反应性表单在提交时显示错误 [英] Reactive Form Using ControlValueAccessor for SubForm Show Errors on Submit
问题描述
我有一个简单的登录页面,其中包含一个响应式表单和一个使用ControlValueAccessor
的子表单组件app-login-form
,它可以正常工作,但是我不知道如何在子表单中显示错误.这是我开始创建更复杂的表单之前的示例.
I have a simple login page with a reactive form and subform component app-login-form
that uses ControlValueAccessor
, which is working, but I can't figure out how to display the errors in the subform. This is an example before I start creating more complex forms.
提交后,我尝试访问子窗体和markAllAsTouched
,但是当我观看类不变的元素时.
When submitted I try to access the subform and markAllAsTouched
, but when I'm watching the elements that the classes don't change.
I made a quick StackBlitz to show what I'm doing. How do I get the error messages to show up when I submit the form?
public onSubmit(event: Event): void {
if (this.form.valid) {
console.log('VALID', this.form.value);
} else {
console.log('INVALID', this.form.value);
Object.keys(this.form.controls).forEach((controlName) => {
console.log('SHOW_ERRORS', controlName);
const control = this.form.get(controlName);
// ISSUE: Nothing changes on the element still ng-untouched, and
// was expecting it to be ng-touched
control.markAllAsTouched();
});
}
}
推荐答案
我会采用略有不同的方法,而不使用ControlValueAccessor
,而是使用常规"子组件并使用ControlContainer
,那么您可以跳过所有markAsTouched
的东西,因为父母会知道孩子身上发生的一切.
I would take a slightly different approach and not use ControlValueAccessor
, but instead a "regular" child component and use ControlContainer
, then you can skip all that markAsTouched
stuff, as parent will be aware of anything going on in child.
父母:
this.form = this.formBuilder.group({});
模板:
<app-login-form></app-login-form>
子组件,我们在其中将formcontrols添加到现有的父表单中:
Child component, where we add formcontrols to existing parent form:
@Component({
selector: "app-login-form",
templateUrl: "./login-form.component.html",
styleUrls: ["./login-form.component.css"],
viewProviders: [
{
provide: ControlContainer,
useExisting: FormGroupDirective
}
]
})
export class LoginFormComponent implements OnInit {
childForm: FormGroupDirective;
constructor(
parentForm: FormGroupDirective,
private fb: FormBuilder
) {
this.childForm = parentForm;
}
ngOnInit() {
this.childForm.form.addControl('username', this.fb.control('', [Validators.required]));
this.childForm.form.addControl('password', this.fb.control('', [Validators.required]));
}
}
然后在模板中仅使用formControlName
而不是[formControl]
,例如:
Then in template you just use formControlName
instead of [formControl]
, like:
<input matInput formControlName="username">
<mat-error *ngIf="childForm.hasError('required', 'username')">Required</mat-error>
还要从子项中删除表单标签,并且还记得在图标中添加type="button"
,否则按钮将被视为submit
.
Also remove the form tags from child, and also remember to add type="button"
in the icon, otherwise button will be considered submit
.
从父表单提交中,您可以删除:control.markAllAsTouched();
From parent form submit you can remove: control.markAllAsTouched();
我会用完整的代码分叉您的stackblitz,但似乎不允许这样做.因此,希望我记得提到我所做的所有更改,否则请提供可以分叉的堆叠闪电战.
这篇关于使用ControlValueAccessor for SubForm的反应性表单在提交时显示错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!