基于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
相关产品推荐
相关产品推荐

