Angular 10 中如何构建包含重复字段集的多层土壤传感器选择表单?
FormGroup 结构设计方案
核心采用嵌套表单结构,外层总FormGroup对应全量表单,每个土壤深度层级对应独立子FormGroup,子FormGroup内根据传感器枚举生成对应FormControl即可,天然支持全表单一次性校验,结构清晰易扩展。
1. 类型定义(可选但推荐,方便TS类型校验)
import { FormGroup, FormControl, Validators } from '@angular/forms'; // 引入你自己的传感器枚举 export enum SensorsEnum { Temperature = "temperature", Humidity = "humidity", PH = "ph", EC = "ec", N = "N", P = "P", K = "K", } // 单个深度层级的表单类型 export interface ISingleLevelForm { [key in SensorsEnum]: FormControl<string | null>; } // 总表单的类型 export interface IRootForm { level5: FormGroup<ISingleLevelForm>; level10: FormGroup<ISingleLevelForm>; level15: FormGroup<ISingleLevelForm>; level30: FormGroup<ISingleLevelForm>; }
2. 表单初始化
抽离公共方法生成单层级表单,避免重复代码:
// 组件内声明总表单变量 sensorForm: FormGroup<IRootForm>; // 把枚举暴露给模板使用 public SensorsEnum = SensorsEnum; // 生成单个深度层级的表单 private createSingleLevelForm(): FormGroup<ISingleLevelForm> { const controlMap: Record<string, FormControl> = {}; // 遍历枚举生成所有传感器对应控件,默认加必填校验 Object.values(SensorsEnum).forEach(sensorKey => { controlMap[sensorKey] = new FormControl(null, Validators.required); }); return new FormGroup(controlMap) as FormGroup<ISingleLevelForm>; } ngOnInit(): void { // 初始化总表单,4个深度层级对应4个子FormGroup this.sensorForm = new FormGroup({ level5: this.createSingleLevelForm(), level10: this.createSingleLevelForm(), level15: this.createSingleLevelForm(), level30: this.createSingleLevelForm() }) as FormGroup<IRootForm>; }
3. 适配表单结构的模板改造
<!-- 外层绑定总表单 --> <form [formGroup]="sensorForm"> <!-- 循环渲染4个深度层级模块 --> <div *ngFor="let depth of [5,10,15,30]" class="card" [formGroupName]="'level'+depth"> <div> <span>Level {{depth}}cm</span> </div> <ul> <li> <div *ngFor="let sensorType of Object.values(SensorsEnum)"> <mat-form-field class="col-12"> <mat-label>Select {{ sensorType }}</mat-label> <!-- 直接用枚举值作为formControlName --> <mat-select [formControlName]="sensorType"> <mat-form-field appearance="outline" class="w-100"> <input matInput #sensorFilter /> </mat-form-field> <mat-option *ngFor="let sensor of sensors | filter: sensorFilter.value" [value]="sensor.id"> {{ sensor.id }} </mat-option> </mat-select> </mat-form-field> </div> </li> </ul> </div> <!-- 总表单校验不通过直接禁用提交按钮 --> <button type="button" (click)="submitForm()" [disabled]="!sensorForm.valid">创建</button> </form>
小提示:如果需要每个层级的搜索过滤器独立,不要共用同一个模板变量,可以通过索引或者层级参数区分过滤器变量
4. 提交逻辑
submitForm(): void { if (this.sensorForm.invalid) { // 触发所有未填写字段的校验提示 this.sensorForm.markAllAsTouched(); return; } // 直接获取结构化的全量表单数据 const formAllData = this.sensorForm.value; // 后续提交逻辑... }
内容的提问来源于stack exchange,提问作者Guru Prakash Ram
相关产品推荐
相关产品推荐

