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

如何在自定义校验器中获取动态创建的表单组内所有表单控件

解决方案:动态表单count字段总和校验
  • 编写自定义校验器
    针对你的需求,需要一个能访问整个表单数组的校验器,计算所有count字段的总和是否超过availableCount。可选择两种校验方式:

    1. 表单数组级校验器(全局校验)
    import { AbstractControl, FormArray, ValidationErrors, ValidatorFn } from '@angular/forms';
    
    export function totalCountValidator(availableCount: number): ValidatorFn {
      return (control: AbstractControl): ValidationErrors | null => {
        const fieldsArray = control as FormArray;
        if (!fieldsArray || fieldsArray.controls.length === 0) return null;
    
        const total = fieldsArray.controls.reduce((sum, fieldGroup) => {
          const countValue = fieldGroup.get('count')?.value || 0;
          return sum + parseInt(countValue, 10);
        }, 0);
    
        return total > availableCount 
          ? { totalExceeded: { max: availableCount, currentTotal: total } } 
          : null;
      };
    }
    
    1. 单个控件级校验器(针对当前输入控件)
    export function countFieldValidator(availableCount: number): ValidatorFn {
      return (control: AbstractControl): ValidationErrors | null => {
        // 从当前控件向上获取父级表单数组
        const fieldsArray = control.parent?.parent as FormArray;
        if (!fieldsArray) return null;
    
        const total = fieldsArray.controls.reduce((sum, fieldGroup) => {
          const countValue = fieldGroup.get('count')?.value || 0;
          return sum + parseInt(countValue, 10);
        }, 0);
    
        return total > availableCount ? { countExceedsTotal: true } : null;
      };
    }
    
  • 绑定校验器到表单

    1. 给表单数组添加全局校验器
      在初始化表单时,将校验器传入表单数组的配置参数:
    this.myForm = this.fb.group({
      fieldsArray: this.fb.array([], [totalCountValidator(this.availableCount)])
    });
    
    1. 给单个count控件添加校验器
      在创建表单组的方法中,为count字段绑定校验器:
    createFieldGroup(): FormGroup {
      return this.fb.group({
        name: ['', Validators.required],
        count: ['', [
          Validators.required,
          Validators.min(0),
          countFieldValidator(this.availableCount)
        ]]
      });
    }
    
  • 触发动态控件变更后的校验
    当添加或删除表单控件时,手动触发表单数组的校验状态更新:

    addField() {
      const fieldsArray = this.myForm.get('fieldsArray') as FormArray;
      fieldsArray.push(this.createFieldGroup());
      fieldsArray.updateValueAndValidity({ emitEvent: true });
    }
    
    removeField(index: number) {
      const fieldsArray = this.myForm.get('fieldsArray') as FormArray;
      fieldsArray.removeAt(index);
      fieldsArray.updateValueAndValidity({ emitEvent: true });
    }
    
  • 模板中显示错误提示

    1. 全局错误提示(对应表单数组校验器)
    <div *ngIf="myForm.get('fieldsArray')?.hasError('totalExceeded')" class="error-message">
      总数量超过可用值 {{ myForm.get('fieldsArray')?.getError('totalExceeded').max }},当前总和为 {{ myForm.get('fieldsArray')?.getError('totalExceeded').currentTotal }}
    </div>
    
    1. 单个控件错误提示(对应控件级校验器)
    <mat-form-field *ngFor="let field of fieldsArray.controls; let i = index">
      <input matInput formControlName="count" placeholder="Count">
      <mat-error *ngIf="field.get('count')?.hasError('countExceedsTotal')">
        当前输入后总数量超过可用值 {{ availableCount }}
      </mat-error>
    </mat-form-field>
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 10:20:21