extjs版本为:2.1
今天写ext界面,遇到了一个让人很郁闷的问题。
首先,在columnmodel中定义某列的editor为comobobox:
{ header: "币种", dataIndex: 'currency', hidden: false, editor: new Ext.form.ComboBox({ store: Ipms.CurrencyType.currencyStore, triggerAction: 'all', displayField: 'name', valueField: 'code', allowBlank: false, editable: false, mode: 'local' }) }
数据源为本地数据,定义如下:
Ipms.CurrencyType.currencyData = [ ['RMB', '人民币'], ['USD', '美元'], ['GBP', '英镑'], ['HKD', '港元'], ['EUR', '欧元'], ['JPY', '日元'], ['CAD', '加拿大元'], ['AUD', '澳大利亚元'] ]; Ipms.CurrencyType.currencyStore = new Ext.data.SimpleStore({ fields: ['code','name'], data: Ipms.CurrencyType.currencyData });
运行代码,界面上下拉框正常显示,数据项也没有问题,如下图:
但是,选中某个条目之后,选中框的值,不是displayField而是valueField,如下图:
按照API的说法,displayField是显示的数据,valueField是相应的值。并且在非gridpanel editor中这种写法是没有问题的,但是这里却出现了问题。这里我想说的是,经验主义害死人啊。
跟踪firebug,最终发现了问题所在。
其实,问题出现在了gridpanel editor而不是combobox。
1. 选择某个选项会触发combobox的onSelect事件,代码如下:
onSelect : function(record, index){ if(this.fireEvent('beforeselect', this, record, index) !== false){ this.setValue(record.data[this.valueField || this.displayField]); this.collapse(); this.fireEvent('select', this, record, index); } },
2.这时combobox的显示的确是displayField对于的数据,combobox的值也的确是valueField的值。如下图:
3.但是一旦控件失去焦点,cell的值就变为valueField对应的值,如下图:
4.跟踪firebug主要触发以下一系列事件。combobox的validateBlur()、TriggerField的triggerBlur()、Field的onBlur()、Editor的completeEdit()、EditorGrid的onEditComplete()等。
也就是说,combobox失去焦点的时候,会触发一系列验证,并且combobox显示为displayField,值为valueField。然后执行editor的一系列验证,他会获取combobox的值,并且把他做为cell的值,这时看到的就是valueField。
解决办法:最简单的就是在columnModel上定义render,如下:
Ipms.CurrencyType.currencyRender = function (value, metadata) { switch (value) { case 'RMB': { metadata.attr = 'ext:qtitle="' + '人民币' + '"'; return '人民币'; } // ... } }
editor和combobox之间这种特殊的关系不知道算不算得上是设计的一个bug,不过如果API清楚的话,还是可以理解的。
参照:http://www.sencha.com/forum/showthread.php?160055-why-valuefield-appear-instade-of-displayfield-when-i-put-combobox-inside-gridpanel