假设我有一个包含子地址组件的结帐表单,如下所示
<form [formGroup]="checkoutForm">
<input formControlName="fullName">
/** more inputs **/
<address-form></address-form>
<button type="submit">Submit</button>
</form>
目前我的checkoutForm构建如下:
this.checkoutForm = this.formBuilder.group({
fullName: ['', Validators.required]
});
addressForm模板如:
<form [formGroup]="addressForm">
<input formControlName="street">
<input formControlName="town"
</form>
建造如:
this.addressForm = this.formBuilder.group({
street: ['', [Validators.required]],
town: ['', Validators.required]
});
现在我遇到的问题是我不知道如何
1 - 仅在子表单有效时验证父表单。
2 - 在提交父表单时验证子表单。
我能想到的唯一方法是让@Output() addressResponse
在this.addressForm.valueChanges
上发出有效性和数据。类似的东西:
this.addressForm.valueChanges.subscribe(data => {
let form = this.addressForm.valid ?
{ valid: true, value: data }:
{ valid: false, value: data };
this.addressResponse.emit(form);
});
父表单组件可以使用此发出的数据。
还有@Input() parentFormSubmitted
我可以用来显示AddressForm模板中的错误
<input formControlName="town"
<div *ngIf="town.hasError('required') && (parentFormSubmitted || town.dirty">Town is a required field</div>
虽然这会起作用,但我不确定它是否是最佳解决方案。我想知道是否有更多的Reactive Form做事方式。 (也许在CheckoutForm组的定义中包含AddressForm组?...)
答案 0 :(得分:3)
您的评论完全正确:
我想知道是否有更多的Reactive Form做事方式。 (也许在CheckoutForm组的定义中包含AddressForm组?...)
您可以在父级中构建表单,并将嵌套组@Input
作为EventEmitter
传递给您的孩子。由于JS中的对象是可变的,因此您不需要this.checkoutForm = this.formBuilder.group({
fullName: ['', [...]],
address: this.formBuilder.group({
street: ['', [...]],
town: ['', [...]]
})
})
将任何更改传递给您的父级,更改将被自动捕获&#34;因此,您可以从父母那里进行所有验证。
所以在父母中构建你的表格,如:
address
然后在您的子标记中将@Input
传递给子级为<address-form [address]="checkoutForm.controls.address"></address-form>
:
@Input
在您的孩子中,您标记@Input() address: FormGroup;
:
<div [formGroup]="address">
<input formControlName="street"><br>
<!-- Validation messages -->
<input formControlName="town">
<!-- Validation messages -->
</div>
并且子项中的模板看起来像:
let rec multiplicity (x, ys) =
match ys with
| [] -> 0
| y::tail when x=y -> 1 + multiplicity(x, tail)
| y::tail -> multiplicity(x, tail)
如上所述,您现在可以处理来自父级的所有验证,因为父级知道子级具有的值:)