Angular 7中FormArray内Select控件值变更时动态显示对应Div
解决Angular 7响应式表单FormArray中Select控件的条件显示问题
嘿,我刚好碰到过类似的场景,给你几个靠谱的解决方案,完全贴合响应式表单的规范,不用再依赖已弃用的[(ngModel)]啦!
首先先纠正一个小细节:你模板里的select用了formControlName="sentCondition",但你的FormGroup里定义的控件名是condition,先把这个统一成condition,不然表单控件会找不到对应的FormControl哦。
方案一:模板中直接访问FormControl的值(最直接)
在FormArray的循环里,每个项都是一个FormGroup,我们可以直接通过这个FormGroup获取condition控件的当前值,用来做*ngIf的判断条件。
模板代码修改:
<!-- 外层包裹FormArray --> <div formArrayName="listFieldArray"> <!-- 循环每个FormArray项 --> <div *ngFor="let fieldGroup of listFieldArray.controls; let i = index" [formGroupName]="i"> <!-- Select控件 --> <div class="clr-row"> <clr-select-container> <select clrSelect formControlName="condition"> <option value="">Select </option> <option value="custom">Custom</option> <option value="between">Between</option> <option value="lessThenEqual">Less then or Equal</option> <option value="moreThen">More then</option> </select> </clr-select-container> </div> <!-- 根据condition值显示对应Div --> <div class="clr-row" *ngIf="fieldGroup.get('condition').value === 'custom'"> <div class="clr-col-4 "> <input clrInput placeholder="From Day" type="date" formControlName="customDayFrom" /> </div> <div class="clr-col-4 "> <input clrInput placeholder="To Day" type="date" formControlName="customDayTo" /> </div> </div> <div class="clr-row" *ngIf="fieldGroup.get('condition').value === 'between'"> <div class="clr-col-4 "> <input clrInput placeholder="From Day" formControlName="customDayFrom" /> </div> <div class="clr-col-4 "> <input clrInput placeholder="To Day" type="date" formControlName="customDayTo" /> </div> </div> <div class="clr-row" *ngIf="fieldGroup.get('condition').value === 'lessThenEqual' || fieldGroup.get('condition').value === 'moreThen'"> <div class="clr-col-4 "> <input clrInput placeholder="Day" formControlName="customDayFrom" /> </div> </div> </div> </div>
组件代码补充:
别忘了给你的FormGroup添加customDayFrom和customDayTo这两个控件,不然日期输入框会绑定失败:
addListFieldsFormGroup(name: string, value: string): FormGroup { return this.formBuilder.group({ 'condition': ['', [Validators.required]], 'name': [name], 'value': [value, [Validators.required]], 'type': ['1', [Validators.required]], 'operator': ['', [Validators.required]], 'operand': ['', [Validators.required]], 'customDayFrom': [''], // 添加日期控件 'customDayTo': [''] // 添加日期控件 }); } // 添加一个getter,方便模板访问FormArray get listFieldArray(): FormArray { return this.form.get('listFieldArray') as FormArray; }
方案二:订阅FormControl的valueChanges(适合需要额外逻辑的场景)
如果需要在condition值变化时做一些额外操作(比如清空不相关的日期输入框),可以在组件类里订阅每个FormGroup中condition控件的valueChanges事件。
组件代码示例:
// 新增添加FormArray项的方法 addListField(name: string = '', value: string = '') { const fieldGroup = this.addListFieldsFormGroup(name, value); // 订阅condition控件的值变化 fieldGroup.get('condition').valueChanges.subscribe((conditionValue) => { // 示例:当选择非custom/between时,清空customDayTo的值 if (conditionValue !== 'custom' && conditionValue !== 'between') { fieldGroup.get('customDayTo').setValue(''); } // 这里可以添加其他业务逻辑,比如校验规则变更等 }); this.listFieldArray.push(fieldGroup); }
模板部分和方案一一样就可以,这样既实现了条件显示,又能处理额外的业务逻辑。
为什么不能用[(ngModel)]?
Angular响应式表单的设计理念是通过FormControl/FormGroup/FormArray统一管理表单状态,混合使用[(ngModel)]会导致表单状态的双向绑定和响应式表单的单向数据流冲突,容易出现状态不一致的问题,所以官方在响应式表单场景下弃用了这种混合写法,推荐直接通过FormControl的value来控制视图。
内容的提问来源于stack exchange,提问作者Anand agrawal
相关产品推荐
相关产品推荐

