Angular14响应式表单模板访问FormArray controls属性报错求助
Angular 14响应式表单:FormArray的controls访问问题解析
问题原因
1. 为何能访问value却无法访问controls?
FormGroup.get('skills')返回的类型是AbstractControl | null,AbstractControl是所有表单控件的基类:
value是AbstractControl的公共属性,FormControl、FormGroup、FormArray都继承并实现了该属性,因此编译时类型检查直接通过。controls是FormGroup和FormArray独有的属性,AbstractControl本身并未定义这个成员,所以TypeScript会抛出“Property 'controls' does not exist on type 'AbstractControl'”的编译错误。
2. 添加hasOwnProperty判断后为何仍报错?
hasOwnProperty('controls')是运行时判断逻辑,而TypeScript的类型检查在编译阶段执行。编译时,TypeScript依然认定reactiveForm.get('skills')的类型是AbstractControl | null,不会因为运行时条件判断自动将其类型推断为FormArray,因此错误无法消除。
不使用getter的解决方法
方法1:模板中用$any()绕过类型检查
Angular模板支持$any()类型断言,强制TypeScript忽略类型校验:
<div formArrayName="skills"> <ng-container *ngFor="let skill of $any(reactiveForm.get('skills')).controls"> <input type="text" placeholder="add skill.." [value]="skill.value"> </ng-container> </div>
方法2:组件类中声明FormArray类型的属性
在组件类中直接定义一个FormArray类型变量,初始化时赋值:
// 组件类新增属性 skillsArray!: FormArray; ngOnInit() { this.reactiveForm = new FormGroup({ // ...其他表单控件 skills: new FormArray([ new FormControl('Cricket'), new FormControl('Football'), new FormControl('Rugby'), ]), }); // 明确类型赋值 this.skillsArray = this.reactiveForm.get('skills') as FormArray; }
模板中直接使用该属性:
<div formArrayName="skills"> <ng-container *ngFor="let skill of skillsArray.controls; let i = index"> <input type="text" placeholder="add skill.." [formControlName]="i"> </ng-container> </div>
方法3:模板中结合as类型断言(需处理null安全)
通过*ngIf先确定控件存在,再用as转换类型:
<div formArrayName="skills"> <ng-container *ngIf="reactiveForm.get('skills') as skillsCtrl"> <ng-container *ngFor="let skill of (skillsCtrl as FormArray).controls"> <input type="text" placeholder="add skill.." [value]="skill.value"> </ng-container> </ng-container> </div>
内容的提问来源于stack exchange,提问作者Alok Shaw
相关产品推荐
相关产品推荐

