Angular:如何在*ngIf中使用*ngFor变量?遇表单控件访问问题
解决Angular中ngFor内动态访问表单控件的ngIf问题
嘿,我一眼就瞅出你代码里的问题啦!你在*ngIf里访问动态命名的表单控件时,字符串拼接的写法完全不符合Angular模板语法,还犯了个小拼写错误~
问题根源
你原来的*ngIf代码:
*ngIf="!rForm.controls['desc']" +{{ i }}+ ".valide"
这写法完全不对——Angular模板表达式不能拆成几段用+拼接,而且valide是拼写失误,正确的表单验证属性是valid。单独用{{i}}能显示是因为那是插值表达式,但和控件访问结合时,必须在一个完整的表达式里完成动态控件名的拼接。
修正后的两种写法
方式1:用控件数组的括号访问
直接在表达式里拼接控件名称字符串:
<li *ngFor="let event of enum ; let i = index"> <textarea pInputTextarea autoResize="autoResize" [(ngModel)]="x[i]" placeholder="xxx" formControlName="desc{{i}}"></textarea> <div class="alert" *ngIf="!rForm.controls['desc' + i].valid"> {{ i }} </div> </li>
方式2:用表单的get()方法(更推荐)
Angular表单的get()方法支持动态路径,而且控件不存在时会返回null,搭配可选链操作符?.能避免潜在报错:
<li *ngFor="let event of enum ; let i = index"> <textarea pInputTextarea autoResize="autoResize" [(ngModel)]="x[i]" placeholder="xxx" formControlName="desc{{i}}"></textarea> <div class="alert" *ngIf="!rForm.get('desc' + i)?.valid"> {{ i }} </div> </li>
额外建议:用FormArray管理动态控件
如果你的表单里有多个类似desc0、desc1的动态控件,更规范的做法是用FormArray管理,不用手动拼接控件名:
组件类代码示例:
import { FormBuilder, FormArray, FormGroup } from '@angular/forms'; // ... rForm!: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit() { this.rForm = this.fb.group({ descs: this.fb.array([]) }); // 根据enum长度初始化控件 this.enum.forEach(() => { (this.rForm.get('descs') as FormArray).push(this.fb.control('')); }); } // 快捷获取FormArray get descs() { return this.rForm.get('descs') as FormArray; }
模板代码示例:
<li *ngFor="let descCtrl of descs.controls; let i = index"> <textarea pInputTextarea autoResize="autoResize" [(ngModel)]="x[i]" placeholder="xxx" [formControl]="descCtrl"></textarea> <div class="alert" *ngIf="!descCtrl.valid"> {{ i }} </div> </li>
这种方式更贴合Angular表单的最佳实践,代码也更清晰易维护~
内容的提问来源于stack exchange,提问作者Med Chedly HAJJAR
相关产品推荐
相关产品推荐

