Angular 10复选框取消选择后值变为undefined的问题求助
Angular表单复选框取消选择后值变为undefined的问题分析与修复
我来帮你拆解一下这个问题的根源,以及对应的修复方案:
问题根源
你当前的代码里犯了一个关键错误:把整个shop对象直接作为FormControl的初始值,但mat-checkbox绑定的表单控件本质上应该存储布尔值(选中/未选中状态),而不是复杂对象。
初始加载时,FormControl的值是完整的shop对象,所以模板里{{someFormControl.value.name}}能正常显示店铺名称;但当你第一次点击复选框取消选择时,mat-checkbox会自动把控件的值切换为false(布尔值),此时someFormControl.value不再是shop对象,自然没有name属性,也就会出现undefined的情况。
另外,模板里的formGroupName="shops"是多余的,因为你已经在父级的FormGroup下操作子控件了,这个属性会导致表单绑定逻辑混乱。
修复步骤
1. 修改TypeScript代码:调整FormControl的初始值
我们需要把FormControl的初始值改为布尔值(默认未选中设为false,如果需要默认选中可以设为true),同时用店铺的唯一标识(比如name,如果名称唯一的话)作为控件的key,方便后续绑定:
loadShops(product: string): void { this.apiService.getShopsThatSellProduct(product).subscribe({ next: data => { this.shops = data; const checkboxes: FormGroup = this.form.get('shops') as FormGroup; // 先清空之前的所有控件,避免残留旧数据 Object.keys(checkboxes.controls).forEach(key => { checkboxes.removeControl(key); }); // 遍历店铺列表,创建存储布尔状态的FormControl this.shops.forEach((shop) => { checkboxes.addControl(shop.name, new FormControl(false)); }); } , error: err => { console.log(err.message); } }); }
2. 修改HTML模板:直接遍历原始店铺列表
不要从表单控件的value里取店铺信息,而是直接遍历你存储的shops数组,这样显示名称时直接用原始对象的属性,同时绑定对应的表单控件key:
<div class="shops"> <mat-form-field> <mat-select placeholder="Shops" > <mat-option *ngFor="let shop of shops"> <mat-checkbox [formControlName]="shop.name"> {{shop.name}}</mat-checkbox> </mat-option> </mat-select> </mat-form-field> </div>
3. (可选)获取选中的店铺列表
如果需要获取用户选中的所有店铺对象,可以添加一个计算属性:
get selectedShops() { const shopsFormGroup = this.form.get('shops') as FormGroup; return this.shops.filter(shop => shopsFormGroup.get(shop.name)?.value); }
这样你就能通过this.selectedShops拿到所有被勾选的店铺数据了。
内容的提问来源于stack exchange,提问作者JeyJ
相关产品推荐
相关产品推荐

