You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular12响应式表单动态FormArray控件验证不生效怎么解决?

问题原因

你遇到的验证不生效问题由两个核心错误导致:

  1. 模板中FormArray循环渲染时,formGroupName写死为固定值0,所有动态项都绑定到了数组第一个FormGroup,后续新增项的绑定完全错误
  2. 你定义的便捷获取器fc返回的是根表单contactInfoForm的直接控件,phone_number、phone_type_id属于FormArray内部子FormGroup的控件,根表单不存在这两个控件,因此验证判断条件永远返回false,提示自然不会触发

解决步骤

第一步:修改组件类,新增FormArray便捷获取器

在你的组件ts文件中新增以下代码,方便后续获取contacts数组:

get contactsArr(): FormArray {
  return this.contactInfoForm.get('contacts') as FormArray;
}

第二步:修改HTML模板,修正绑定逻辑

  1. 修正FormArray循环逻辑,添加索引变量,动态绑定formGroupName
  2. 替换验证判断逻辑,从当前循环的子FormGroup中获取控件
  3. 补充缺失的表单绑定和移除按钮逻辑

修改后的模板核心片段如下:

<div class="row">
  <!-- 修正循环,添加索引,绑定动态formGroupName -->
  <div formArrayName="contacts" class="col-md-12" *ngFor="let contact of contactsArr.controls; let i = index">
    <div [formGroupName]="i" class="row">
      <div class="col-12 col-md-4">
        <div class="form-group">
          <label for="phone_number">手机号码:<span style="color:red;">*</span></label>
          <div class="input-group mb-4">
            <ngx-intl-tel-input [cssClass]="'form-control mb-4'" [preferredCountries]="preferredCountries" [enableAutoCountrySelect]="false" [enablePlaceholder]="true" [searchCountryFlag]="true" [searchCountryField]="[SearchCountryField.Iso2, SearchCountryField.Name]"
              [selectFirstCountry]="false" [selectedCountryISO]="CountryISO.Nigeria" [phoneValidation]="true" [separateDialCode]="true" name="phone_number" formControlName="phone_number">
            </ngx-intl-tel-input>
          </div>
        </div>
        <!-- 修正验证判断:从当前contact子FormGroup获取控件 -->
        <div *ngIf="contact.get('phone_number').touched && contact.get('phone_number').invalid">
          <div *ngIf="contact.get('phone_number').hasError('required')">
            <div class="text-danger">
              手机号码为必填项!
            </div>
          </div>
          <div *ngIf="contact.get('phone_number').hasError('validatePhoneNumber')">
            <div class="text-danger">
              手机号码格式无效!
            </div>
          </div>
        </div>
      </div>
      <div class="col-12 col-md-4">
        <div class="form-group">
          <label for="phone_type_id">号码类型:<span style="color:red;">*</span></label>
          <ng-select [items]="phonetypes" [selectOnTab]="true" [searchable]="true" bindValue="id" bindLabel="type_name" placeholder="选择号码类型" [multiple]="false" [clearable]="true" required formControlName="phone_type_id">
          </ng-select>
        </div>
        <!-- 同样修正号码类型的验证判断 -->
        <div *ngIf="contact.get('phone_type_id').touched && contact.get('phone_type_id').invalid">
          <div *ngIf="contact.get('phone_type_id').hasError('required')">
            <div class="text-danger">
              号码类型为必填项!
            </div>
          </div>
        </div>
      </div>
      <div class="col-12 col-md-2">
        <div class="form-group">
          <label for="is_primary_contact_number">是否为主号码:</label><br>
          <!-- 补充缺失的formControl绑定 -->
          <input type="checkbox" class="form-check-input" id="is_primary_contact_number" formControlName="is_primary_contact_number">
        </div>
      </div>
      <div class="col-12 col-md-2">
        <div class="form-group">
          <!-- 补充移除按钮的点击逻辑 -->
          <button type="button" class="btn btn-danger float-right" (click)="contactsArr.removeAt(i)"><i class="fas fa-minus"></i> 移除</button>
        </div>
      </div>
    </div>
  </div>
</div>

修改完成后,所有FormArray内部控件的验证规则即可正常触发。

内容的提问来源于stack exchange,提问作者user11352561

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:45:05