【问题标题】:Problem with validate formGroup inside formArray在 formArray 中验证 formGroup 的问题
【发布时间】:2019-05-28 14:07:28
【问题描述】:

我正在创建一个带有角材料垫表的表格。

我在编写应用程序时使用了响应式表单,表单启动看起来像这样:

myForm = this.fb.group({
    settings: this.fb.array([])
});

我的表单是一个 formGroup,其中包含一个 formArray 控件(设置)。

设置 formArray 包含每个设置的 formGroup(mat-table 中的每一行都是一个 formGroup 并包含多个控件)。

当我尝试向它添加验证时,我的问题就开始了。

如果我只有一个带有 formControl 的 formGroup,其中一个是 Validators.required,例如,在我添加一些值之前,表单是无效的,然后它会变为有效状态。

但是,在表单数组中使用 formGroup 时,即使在 require 字段中添加了一些值,表单状态仍然无效(我什至控制台记录表单以查看内部值是否已更改并且确实如此)。

此外,当我尝试使用 valueChange().subscribe... 捕获更改时,该事件仅在我从 formArray 推送/删除组时触发,并且从不会在设置组内的现有控件发生更改时触发。

如何在数组内的组中侦听内部更改事件,然后对它们使用一些自定义估值?

【问题讨论】:

  • 澄清一下,您有一个带有 FormArray 子级的顶级 FormGroup,其中数组中的每个项目都是 FormControls 的 FormGroup?
  • 是的,我这样做是因为表单将包含其他数据,并且表格中的每一行(formArray 中的元素)包含字段数

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


【解决方案1】:

没有看到更多的代码......很难猜测可能出了什么问题。

但这是我的一些代码供参考:

组件代码

  get addresses(): FormArray {
    return <FormArray>this.customerForm.get('addresses');
  }

  ngOnInit() {
    this.customerForm = this.fb.group({
      firstName: ['', [Validators.required, Validators.minLength(3)]],
      lastName: ['', [Validators.required, Validators.maxLength(50)]],
      addresses: this.fb.array([this.buildAddress()])
    });
  }

  addAddress(): void {
    this.addresses.push(this.buildAddress());
  }

  buildAddress(): FormGroup {
    return this.fb.group({
      addressType: 'home',
      street1: ['', Validators.required],
      street2: '',
      city: '',
      state: '',
      zip: ''
    });
  }

模板

    <div formArrayName="addresses"
         *ngFor="let address of addresses.controls; let i=index">

        <div class="form-group row mb-2">
          <label class="col-md-2 col-form-label"
                 attr.for="{{'street1Id' + i}}">Street Address 1</label>
          <div class="col-md-8">
            <input class="form-control"
                   id="{{'street1Id' + i}}"
                   type="text"
                   placeholder="Street address (required)"
                   formControlName="street1"
                   [ngClass]="{'is-invalid': (address.controls.street1.touched || 
                                              address.controls.street1.dirty) && 
                                              !address.controls.street1.valid }">
            <span class="invalid-feedback">
              <span *ngIf="address.controls.street1.errors?.required">
                Please enter your street address.
              </span>
            </span>
          </div>
        </div>
    </div>

你可以在这里找到完整的项目:https://github.com/DeborahK/Angular-ReactiveForms/tree/master/Demo-Final

【讨论】:

    【解决方案2】:

    我正在做以下事情:!

    const array = (this.fg.get('addresses') as FormArray).controls;
    array.push(this.fb.group({...}));
    

    虽然应该是(没有controls

    const array = (this.fg.get('addresses') as FormArray);
    array.push(this.fb.group({...}));
    

    【讨论】:

      【解决方案3】:

      您使用的嵌套结构不应影响验证规则。如果 FormControl 无效,则无效状态将冒泡到根 AbstractControl(在这种情况下是您的“myForm”FormGroup)。 Angular 将为您处理所有这些。

      查看这个 stackblitz 示例,其表单结构与您描述的相同:https://stackblitz.com/edit/angular-xhppjs?file=src%2Fapp%2Fapp.component.html

      奖金信息:

      不要试图捕获 valueChanges 来强制执行验证规则。如果你只是按照 Angular 的意图使用验证器函数,你会过得更轻松。 (https://angular.io/guide/form-validation#reactive-form-validation)

      这里是 Angular 内置的列表:https://angular.io/api/forms/Validators

      这里是关于创建自定义验证器函数的部分,如果内置函数不适合您的需要:https://angular.io/guide/form-validation#custom-validators

      【讨论】:

        【解决方案4】:

        感谢您的回复,我设法解决了 html 文件中的问题。

        当我启动 mat-table 时,我做了以下事情: [数据源] = settings.value

        这样做会显示表格中的值,但没有更新 formArray 中的控件...

        我通过将其更改为 settings.controls 并将 [formGroupName]=index 添加到每个 mat-cell 来解决它

        感谢您的帮助。

        【讨论】:

          猜你喜欢
          • 2017-11-09
          • 2021-03-29
          • 2018-09-03
          • 2021-02-01
          • 2018-09-11
          • 1970-01-01
          • 2021-03-06
          • 2019-08-03
          • 2020-11-21
          相关资源
          最近更新 更多