验证父表单Angular 2+中的表单

时间:2017-09-28 10:18:58

标签: forms angular angular-reactive-forms angular-forms

假设我有一个包含子地址组件的结帐表单,如下所示

<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() addressResponsethis.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组?...)

1 个答案:

答案 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)

如上所述,您现在可以处理来自父级的所有验证,因为父级知道子级具有的值:)