Angular编辑项时出现“Property ... does not exist on type”错误求助
问题分析
你遇到的"Property ... does not exist on type"错误,核心原因有三个:
- 表单结构设计错误,顶层FormGroup中定义的
read/write/delete等控件,和模板中每个模块独立的权限字段不匹配 - 在
ngOnInit中错误地直接访问数组data1.actions的属性(比如data1.actions.id),但actions是AllModules[]类型,数组本身没有这些属性 - 模板中混合使用
ngModel和formControlName,且绑定的控件不存在于当前FormGroup中
解决方案
1. 重构表单结构,用FormArray处理多模块权限
每个模块都有独立的权限字段,需要用FormArray管理动态表单控件,替代顶层单个控件:
constructor(...) { this.form = this._formBuilder.group({ id: [null], name: [null, Validators.required], branches: [null, Validators.required], // 用FormArray存储每个模块的权限组 modulesPermissions: this._formBuilder.array([]) }) } // 辅助方法:创建单个模块的权限表单组 private createModulePermissionGroup(module: AllModules): FormGroup { return this._formBuilder.group({ moduleId: [module.id], read: [module.read ?? false], write: [module.write ?? false], delete: [module.delete ?? false] }) }
在获取模块数据后初始化FormArray:
seeMeModules() { this.selectedModule = this.serviceGroup.getAllModule().subscribe( resp => { this.selectedAllModules = resp; const permissionsArray = this.form.get('modulesPermissions') as FormArray; permissionsArray.clear(); // 为每个模块添加权限表单组 this.selectedAllModules.forEach(module => { permissionsArray.push(this.createModulePermissionGroup(module)); }); this.allCategories = this.filterGetAllCategories(resp) }); }
2. 修复ngOnInit中的表单赋值逻辑
data1.actions是数组,需遍历匹配模块后更新对应表单控件:
ngOnInit(): void { this.seeMeBranch(); this.seeMeModules(); const data1: GrupoSegurancaInterface = this.route.snapshot.data['element']; // 赋值基础字段 this.form.patchValue({ id: data1.id, name: data1.name, branches: data1.branches.id }); // 等待模块数据加载后同步权限 this.selectedModule.add(() => { const permissionsArray = this.form.get('modulesPermissions') as FormArray; data1.actions.forEach(action => { const groupIndex = permissionsArray.controls.findIndex( ctrl => ctrl.get('moduleId')?.value === action.id ); if (groupIndex !== -1) { permissionsArray.at(groupIndex).patchValue({ read: action.read, write: action.write, delete: action.delete }); } }); }); }
3. 修改模板,正确绑定FormArray控件
去掉错误的ngModel和顶层formControlName,改用formArrayName和formGroupName绑定:
<mat-tab label="Permissões"> <section> <h4>Modulos do Grupo de Segurança</h4> <hr /> <form [formGroup]="form"> <!-- 绑定modulesPermissions FormArray --> <div formArrayName="modulesPermissions"> <div *ngFor="let category of allCategories" class="modulecheckbox"> <h4>{{ category.description }}</h4> <div class="checkboxpermissions"> <mat-checkbox *ngFor=" let module of filterItemsByCategory(selectedAllModules, category); let i = index " [value]="module.id.toString()" > {{ module.name }} <!-- 绑定对应索引的权限表单组 --> <div class="checkboxoptions" [formGroupName]="i"> <mat-checkbox formControlName="read">Leitura</mat-checkbox> <mat-checkbox formControlName="write">Escrita</mat-checkbox> <mat-checkbox formControlName="delete">Exclusão</mat-checkbox> </div> </mat-checkbox> </div> </div> </div> </form> </section> <hr /> </mat-tab>
4. 修复onSubmit中的数据组装逻辑
从FormArray中读取权限数据,确保和接口格式匹配:
onSubmit(){ const formValue = this.form.value; const permissionsArray = this.form.get('modulesPermissions') as FormArray; let data = { "id": formValue.id, "name": formValue.name, "branches": this.branchesControl.value.map((element:any) =>{ return { "id" : element } }), "actions": permissionsArray.controls.map(ctrl => { const ctrlValue = ctrl.value; return { "module":{ "id": ctrlValue.moduleId }, "read": ctrlValue.read, "write": ctrlValue.write, "delete": ctrlValue.delete } }) } this.serviceGroup.save(data).subscribe(result => this.onSucess(), erro => this.onError() ); }
额外类型安全优化
- 修正
selectedAllBranches的类型:
selectedAllBranches: Branches[] = [];
- 优化
idsToToppings方法的类型定义:
idsToToppings(ids: number[]): string[] { return this.selectedAllBranches .filter(t => ids.includes(t.id)) .map(element => element.name); }
关键错误总结
- 混淆数组类型和单个元素类型:
data1.actions是数组,不能直接访问id/read等属性,必须遍历操作单个元素 - 表单结构与数据结构不匹配:多模块权限需用
FormArray管理,而非顶层单个控件 - 模板错误绑定不存在的表单控件,触发TypeScript类型检查报错
内容的提问来源于stack exchange,提问作者Jeferson Carlos
相关产品推荐
相关产品推荐

