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

基于JSON的动态Angular表单:无法在'rubrique.formControl'上创建validator属性

我来帮你搞定这个动态Angular表单的问题,先拆解下你遇到的核心问题,然后一步步修复:

核心问题诊断

你目前遇到的错误主要来自四个方面:

  • TypeScript循环中数组层级访问错误+拼写错误(lenght→length)
  • FormControl添加到FormGroup的方式不正确
  • HTML中FormControl的绑定语法错误
  • mat-error里的拼写错误(erros→errors)

1. 修复TypeScript的表单控件初始化逻辑

你的循环嵌套完全搞错了层级关系,sections是数组,必须逐层遍历每个元素的子属性,而且lenght是拼写错误。另外,form.addControl需要传入控件名称和FormControl实例,不能直接传入控件对象。

修改后的TS代码:

// 先在组件类中声明FormGroup
form: FormGroup;

// 初始化表单的函数
initDynamicForm() {
  // 先创建空的FormGroup
  this.form = new FormGroup({});

  // 逐层遍历JSON结构
  for (let i = 0; i < this.sections.length; i++) {
    const currentSection = this.sections[i];
    
    for (let j = 0; j < currentSection.sousSections.length; j++) {
      const currentSousSection = currentSection.sousSections[j];
      
      for (let k = 0; k < currentSousSection.lignes.length; k++) {
        const currentLigne = currentSousSection.lignes[k];
        
        for (let l = 0; l < currentLigne.rubriques.length; l++) {
          const currentRubrique = currentLigne.rubriques[l];
          
          // 根据是否必填创建FormControl
          const control = currentRubrique.isRequired 
            ? new FormControl('', Validators.required) 
            : new FormControl('');
          
          // 用rubrique的唯一code作为控件名,添加到FormGroup
          this.form.addControl(currentRubrique.codeRubrique, control);
          
          // 把控件实例绑定到rubrique对象上,方便HTML引用
          currentRubrique.formControl = control;
        }
      }
    }
  }
}

2. 修复HTML的表单绑定与错误提示

你的HTML有几个关键错误:缺少FormGroup绑定、FormControl语法错误、错误提示的拼写错误。修改后的代码片段如下:

<!-- 外层必须绑定FormGroup -->
<form [formGroup]="form">
  <button mat-raised-button class="enregistrer-color">Enregistrer</button>
  <button mat-raised-button class="valider-color">Valider</button>

  <div *ngFor="let section of sections; let l = index">
    <mat-toolbar color="accent">
      <div color="primary" class="section-title">{{ section.libelleSection }}</div>
    </mat-toolbar>

    <div *ngFor="let sousSection of section.sousSections; let k = index">
      <mat-toolbar color="warn" class="section-title">{{ sousSection.libelleSousSection }}</mat-toolbar>

      <div class="container">
        <div *ngFor="let ligne of sousSection.lignes; let j = index">
          <mat-grid-list cols="2" rowHeight="75px">
            <div *ngFor="let rubrique of ligne.rubriques; let i = index">
              <div class="example-container">
                <mat-grid-tile>
                  <!-- 日期类型控件补全示例 -->
                  <div *ngIf="rubrique.typeRubrique === 'date'">
                    <label>{{ rubrique.description }} : </label>
                    <mat-form-field>
                      <input matInput [formControl]="rubrique.formControl" type="date">
                      <mat-error *ngIf="rubrique.formControl.errors?.required && (rubrique.formControl.dirty || rubrique.formControl.touched)">
                        Ce champs est <strong>obligatoire !</strong>
                      </mat-error>
                    </mat-form-field>
                  </div>

                  <!-- 列表类型控件修复 -->
                  <div *ngIf="rubrique.typeRubrique === 'liste'">
                    <label>{{ rubrique.description }} : </label>
                    <mat-form-field>
                      <!-- 用[formControl]做属性绑定,不是formControl字符串 -->
                      <mat-select [formControl]="rubrique.formControl">
                        <mat-option *ngFor="let option of rubrique.options" [value]="option.label">
                          {{option.valeur}}
                        </mat-option>
                      </mat-select>
                      <!-- 修复errors拼写,用?.避免空指针,加上交互判断优化体验 -->
                      <mat-error *ngIf="rubrique.formControl.errors?.required && (rubrique.formControl.dirty || rubrique.formControl.touched)">
                        Ce champs est <strong>obligatoire !</strong>
                      </mat-error>
                    </mat-form-field>
                  </div>
                </mat-grid-tile>
              </div>
            </div>
          </mat-grid-list>
        </div>
      </div>
    </div>
  </div>
</form>

3. 额外优化建议

  • 不需要维护四维数组this.controls,因为已经把FormControl直接绑定到了rubrique对象上,直接通过rubrique.formControl访问即可
  • 给mat-error加上dirty || touched判断,只有用户交互过控件后才显示错误,提升用户体验
  • 确保你的模块中导入了ReactiveFormsModule,否则响应式表单无法正常工作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:03:51