在父表单中验证表单 Angular 2+
Validating a form within a parent form Angular 2+
假设我有一个包含子地址组件的结帐表单,如下所示
<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 组?...)
您的评论完全正确:
I was wondering if there a more Reactive Form way of doing things. (Maybe include the AddressForm group in the definition of the CheckoutForm group?...)
您可以在 parent 中构建表单,并将嵌套组 address
作为 @Input
传递给 child。由于 JS 中的 objects 是可变的,您不需要 EventEmitter
将任何更改从 child 传递到您的 parent,更改将被捕获 "automatically" 并且因此,您可以从 parent.
进行所有验证
因此,在 parent 中构建您的表单:
this.checkoutForm = this.formBuilder.group({
fullName: ['', [...]],
address: this.formBuilder.group({
street: ['', [...]],
town: ['', [...]]
})
})
然后在您的 child 标签中将 address
作为 @Input
:
传递给 child
<address-form [address]="checkoutForm.controls.address"></address-form>
在你的 child 中标记 @Input
:
@Input() address: FormGroup;
child 中的模板如下所示:
<div [formGroup]="address">
<input formControlName="street"><br>
<!-- Validation messages -->
<input formControlName="town">
<!-- Validation messages -->
</div>
如前所述,您现在可以处理来自 parent 的所有验证,因为 parent 知道 child 的值:)
假设我有一个包含子地址组件的结帐表单,如下所示
<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 组?...)
您的评论完全正确:
I was wondering if there a more Reactive Form way of doing things. (Maybe include the AddressForm group in the definition of the CheckoutForm group?...)
您可以在 parent 中构建表单,并将嵌套组 address
作为 @Input
传递给 child。由于 JS 中的 objects 是可变的,您不需要 EventEmitter
将任何更改从 child 传递到您的 parent,更改将被捕获 "automatically" 并且因此,您可以从 parent.
因此,在 parent 中构建您的表单:
this.checkoutForm = this.formBuilder.group({
fullName: ['', [...]],
address: this.formBuilder.group({
street: ['', [...]],
town: ['', [...]]
})
})
然后在您的 child 标签中将 address
作为 @Input
:
<address-form [address]="checkoutForm.controls.address"></address-form>
在你的 child 中标记 @Input
:
@Input() address: FormGroup;
child 中的模板如下所示:
<div [formGroup]="address">
<input formControlName="street"><br>
<!-- Validation messages -->
<input formControlName="town">
<!-- Validation messages -->
</div>
如前所述,您现在可以处理来自 parent 的所有验证,因为 parent 知道 child 的值:)