最近碰到个combobox的问题,当combobox里面有多个相同的displayField,无论你选哪一个,只要组件失去焦点后,调用getValue()时总是返回第一个valueField,
通过debug源码,发现combobox的beforeBlur事件中调用了assertValue的方法,而问题就是出在这里,原因写在注释中:
assertValue : function(){
var val = this.getRawValue(),
rec = this.findRecord(this.displayField, val);
if(!rec && this.forceSelection){
if(val.length > 0 && val != this.emptyText){
this.el.dom.value = Ext.value(this.lastSelectionText, '');
this.applyEmptyText();
}else{
this.clearValue();
}
}else{
if(rec){
/*
因为前面this.findRecord(this.displayField, val)找到的是第一条符合条件的record(即第一条record),如果我们选择的选项不是第一条的话,下面的this.value == rec.get(this.valueField)就无法成立,代码将会用第一条record的value覆盖掉我们原来选择的value,所以导致只要失去焦点后再去getValue,就一直返回第一条记录的value的问题*/
if (val == rec.get(this.displayField) &&
this.value == rec.get(this.valueField)){
return;
}
val = rec.get(this.valueField || this.displayField);
}
this.setValue(val);
}
}
解决方法也很简答,覆盖掉此方法即可
代码如下:
Ext.override(Ext.form.ComboBox, {
assertValue: function () {
var val = this.getRawValue(),
rec = this.findRecord(this.displayField, val);
if (!rec && this.forceSelection) {
if (val.length > 0 && val != this.emptyText) {
this.el.dom.value = Ext.value(this.lastSelectionText, '');
this.applyEmptyText();
} else {
this.clearValue();
}
} else {
if (rec) {
//移除this.value == rec.get(this.valueField)
if (val == rec.get(this.displayField)) {
return;
}
val = rec.get(this.valueField || this.displayField);
}
this.setValue(val);
}
}
});
后来查看官方文档,发现此问题在3.4以后就修复了,唉,用太老的版本开发就是会有一些很莫名其妙的问题。。。