为什么Angular中select下拉框重新赋值option列表后显示错误选中值?
问题原因
- 核心问题是值类型不匹配:使用
value="{{preset.id}}"的插值写法会把数字类型的preset.id强制转为字符串存入原生DOM的value属性,而userSettings.defaultPreset是数字类型,二者全等对比(2 === "2")结果为false,Angular无法匹配到对应的option。 - 当你重新赋值
userPresets数组时,所有option会被销毁重建,此时ngModel找不到匹配的option值,会自动选中第一个未禁用的option,也就是id为1的预设。刷新页面后恢复正常是初始化时序导致的巧合,不属于稳定表现。
修复方案
1. 修改value绑定方式
将插值写法改为Angular属性绑定,保留id的原始数字类型:
<select class="form-control" name="bg" (change)="patchPreset($event)" [ngModel]="userSettings?.defaultPreset"> <!-- 占位option同样改为属性绑定,避免null值类型问题 --> <option [value]="null" disabled>Select Preset</option> <option *ngFor="let preset of userPresets" [value]="preset.id">{{preset.name}}</option> </select>
如果后续需要绑定整个preset对象作为选中值,可以改用[ngValue]="preset"写法。
2. 可选优化:添加trackBy减少DOM重绘
给*ngFor添加trackBy函数,避免数组更新时全量销毁重建option,降低性能损耗同时减少变更检测异常概率:
首先在ts文件中定义trackBy方法:
trackByPresetId(index: number, preset: {id: number, name: string}): number { return preset.id; }
再修改ngFor代码:
<option *ngFor="let preset of userPresets; trackBy: trackByPresetId" [value]="preset.id">{{preset.name}}</option>
修改完成后重新拉取userPresets数组时,ngModel绑定的数字id可以正确匹配到同类型的option value,不会再出现自动跳转第一个选项的问题。
内容的提问来源于stack exchange,提问作者Stefan T
相关产品推荐
相关产品推荐

