Angular中动态生成表单控件并按需配置校验的实现方案
问题描述
现有如下表单配置对象:
[ { "labelName": "Name", "inputType": "textbox", "inputValues": "", "mandatory": "yes" }, { "labelName": "Email", "inputType": "textbox", "inputValues": "", "mandatory": "yes" }, { "labelName": "address 2", "inputType": "textarea", "inputValues": null, "mandatory": "yes" }, { "labelName": "City", "inputType": "dropdown", "inputValues": null, "mandatory": "no" } ]
需基于该对象生成Angular表单控件,现有基础TS/HTML代码,要实现两个需求:
- 根据
mandatory字段动态设置必填校验,值为yes时添加校验规则 - 根据
inputType字段渲染对应控件,如textbox对应文本框、textarea对应文本域、dropdown对应下拉选择框
解决方案
一、TS代码优化(动态处理校验规则)
修改表单初始化逻辑,根据mandatory字段判断是否添加必填校验:
FormGroup: FormGroup; initForm() { const formControls: {[key: string]: FormControl} = {}; this.fieldsData.forEach(field => { // 初始化校验规则数组 const validators: ValidatorFn[] = []; // 仅当mandatory为yes时添加必填校验 if (field.mandatory === 'yes') { validators.push(Validators.required); } // 用配置中的inputValues作为控件默认值,无值则设为空字符串 formControls[field.labelName] = new FormControl(field.inputValues || '', validators); }); this.FormGroup = new FormGroup(formControls); }
调用时只需在组件初始化阶段(比如ngOnInit)执行this.initForm()即可。
二、HTML代码优化(动态渲染对应控件)
使用Angular的ngSwitch指令根据inputType匹配渲染不同控件,同时补充必填标识和错误提示:
<form [formGroup]="FormGroup"> <div *ngFor="let field of fieldsData" class="form-group"> <label> {{field.labelName}} <!-- 必填字段添加星号标识 --> <span *ngIf="field.mandatory === 'yes'" class="required-mark">*</span> </label> <!-- 根据inputType渲染对应控件 --> <ng-container [ngSwitch]="field.inputType"> <!-- 文本框 --> <input *ngSwitchCase="'textbox'" type="text" formControlName="{{field.labelName}}" placeholder="请输入{{field.labelName}}" > <!-- 文本域 --> <textarea *ngSwitchCase="'textarea'" formControlName="{{field.labelName}}" placeholder="请输入{{field.labelName}}" rows="3" ></textarea> <!-- 下拉选择框 --> <select *ngSwitchCase="'dropdown'" formControlName="{{field.labelName}}" > <option value="" disabled selected>请选择{{field.labelName}}</option> <!-- 遍历inputValues渲染下拉选项,若无选项则仅显示默认提示 --> <option *ngFor="let option of field.inputValues || []" [value]="option">{{option}}</option> </select> <!-- 默认渲染文本框(兼容未定义的inputType) --> <input *ngSwitchDefault type="text" formControlName="{{field.labelName}}" placeholder="请输入{{field.labelName}}" > </ng-container> <!-- 校验错误提示 --> <div *ngIf="FormGroup.get(field.labelName)?.invalid && (FormGroup.get(field.labelName)?.dirty || FormGroup.get(field.labelName)?.touched)" class="error-text"> <span *ngIf="FormGroup.get(field.labelName)?.errors?.['required']">{{field.labelName}}为必填项</span> </div> </div> <button class="btn-submit" type="button" [disabled]="!FormGroup.valid" style="margin-top: 20px" (click)="SubmitDemo()" > 提交 </button> </form>
内容的提问来源于stack exchange,提问作者user3653474
相关产品推荐
相关产品推荐

