【问题标题】:Validating a form within a parent form Angular 2+在父表单Angular 2+中验证表单
【发布时间】:2018-03-10 01:14:10
【问题描述】:

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

<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>

虽然这可行,但我不确定它是否是最佳解决方案。我想知道是否有更多反应形式的做事方式。 (也许在 CheckoutForm 组的定义中包括 AddressForm 组?...)

【问题讨论】:

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


    【解决方案1】:

    您的评论完全正确:

    我想知道是否有更多反应形式的做事方式。 (也许在 CheckoutForm 组的定义中包含 AddressForm 组?...)

    您可以在父级中构建表单,并将嵌套组address 作为@Input 传递给您的子级。由于 JS 中的对象是可变的,因此您不需要 EventEmitter 将任何更改从子级传递给您的父级,更改将被“自动”捕获,因此您可以从父级进行所有验证。

    所以在父级中构建您的表单,例如:

    this.checkoutForm = this.formBuilder.group({
      fullName: ['', [...]],
      address: this.formBuilder.group({
        street: ['', [...]],
        town: ['', [...]]
      })
    })
    

    然后在您的子标签中将address 作为@Input 传递给子标签:

    <address-form [address]="checkoutForm.controls.address"></address-form>
    

    在您的孩子中标记@Input

    @Input() address: FormGroup;
    

    child 中的模板如下所示:

    <div [formGroup]="address">
      <input formControlName="street"><br>
      <!-- Validation messages -->
      <input formControlName="town">
      <!-- Validation messages -->
    </div>
    

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

    【讨论】:

    • 感谢@AJT_82 的回答。如果我有两个地址实例指向我的父表单中的同一个子组件,我会怎么做。我是否必须在主 checkoutForm 组中定义两个单独的 addressForm 组?
    • 您可能需要一个表单数组,您可以在其中推送这两个地址,或者如果这是动态的,您也可以动态推送地址。像这样的东西:stackoverflow.com/a/43521492/6294072
    • 这个想法是为地址设置一个复选框,该地址将出现在 DOM 中,但仅在选中复选框时才显示。你推荐formArray吗?
    • 这一切都取决于。您是否还有多个地址组?如果是这样并且数字是动态的,请使用表单数组。如果您知道只有两个地址,这完全取决于您。如果我知道我只有两组,我可能会选择只有两组而不是表单数组,特别是如果您对何时显示这些有某种条件:)
    • 谢谢先生。您的 cmets 和方向非常有帮助
    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 2016-08-19
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    相关资源
    最近更新 更多