Chrome下拉框绑定对象偶现Null,IE正常的技术求助
嘿,这个问题我之前处理过类似的情况,核心原因大概率是异步数据加载和表单赋值的顺序不匹配,再加上Chrome和IE对异步操作、表单控件值的处理差异导致的。
为什么会出现这个问题?
你在ngOnInit里同时调用了getAllCostCenetrs()(异步请求数据)和populateHeaderDet()(同步赋值表单)。因为HTTP请求是异步的,populateHeaderDet()很可能在iCostCenter还没拿到后端返回的数据时就执行了——这时候iCostCenter还是初始的空数组,find()方法会返回undefined,你把这个undefinedpatch到表单控件里,Chrome的PrimeNG下拉框对undefined的处理和IE不一样,就表现为绑定对象变成了null;而IE可能对这种情况做了兼容处理,所以看起来正常。
另外,你的下拉框filterBy属性写的是value.cost_center_name,这可能也是个隐患:PrimeNG的filterBy应该直接指定选项对象的属性名(比如cost_center_name),而不是带value.前缀,这个写法在Chrome里可能导致过滤逻辑出错,间接引发控件值异常。
解决方案
1. 确保表单赋值在数据加载完成后执行
把populateHeaderDet()放到getAllCostCenetrs()的订阅回调里,保证只有当iCostCenter拿到数据后,才去匹配并赋值表单:
getAllCostCenetrs() { this._appParams.getAllCostCenters() .subscribe( data => { this.iCostCenter = data.result; // 数据加载完成后再执行表单赋值 this.populateHeaderDet(); }, error => console.error('GetAllCostCenetrs Method: ', error)); }
然后修改ngOnInit,只调用getAllCostCenetrs()即可:
ngOnInit() { this.getAllCostCenetrs(); }
2. 修正filterBy属性的写法
把下拉框的filterBy从value.cost_center_name改成cost_center_name,符合PrimeNG的官方用法:
<p-dropdown [options]="iCostCenter" optionLabel="cost_center_name" styleClass="form-control" formControlName="costCenter" id="costCenterId" name="costCenter" dataKey="cost_center_id" [filter]="true" filterBy="cost_center_name"> </p-dropdown>
3. 额外的容错处理(可选)
在populateHeaderDet()里加个判断,避免iCostCenter为空时执行find():
populateHeaderDet() { if (!this.iCostCenter || this.iCostCenter.length === 0) return; const matchedCostCenter = this.iCostCenter.find(cc => cc.cost_center_name === this.iRequest.costCenter.cost_center_name); if (matchedCostCenter) { this.ersaForm.patchValue({ costCenter: matchedCostCenter }); } }
这样调整后,应该就能解决Chrome里下拉框绑定对象变null的问题了,同时也能让代码的健壮性更好~
内容的提问来源于stack exchange,提问作者rgoal

