在Ext 2.2 中,如果使用Ext.form.ComboBox 作为editor,并设置了store,在选择后,在表格单元中显示的是store中的valueField,显然不符合实际使用习惯。如果要改变单元格的展示方式,应该在ColumnModel 配置column时设置renderer,顾名思义就是一个渲染器,默认参数有(value, metadata, record, rowIndex, colIndex, store),具体说明见API
测试如:
dataColumnModel = new Ext.grid.ColumnModel([
{
header: 'Party',
dataIndex: 'IDparty',
width: 150,
editor: new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
store:new Ext.data.SimpleStore({
fields:['partyValue', 'partyName'],
data: [['1','No Party'],['2','Federalist'],['3','Democratic-Republican'],['4','Democratic'],['5','Whig'],['6','Republican']]
}),
mode: 'local',
displayField: 'partyName',
valueField: 'partyValue',
listClass: 'x-combo-list-small'
})
,renderer: function(value, metadata, record, rowIndex, colIndex, store){
console.log(this);
// how to get the editor.store.data ?
return value;
}
}
]);
具体例子来源: Tutorial:Grid PHP SQL Part7
但似乎没有办法在renderer内部访问当前column的editor。
这个应该是个常见需求,搜索官方论坛后果然有所获。有人找到了临时解决方案:
// link http://extjs.com/forum/showthread.php?p=255483
Ext.override(Ext.grid.GridView, {
getColumnData : function(){
var cs = [], cm = this.cm, colCount = cm.getColumnCount();
for(var i = 0; i < colCount; i++){
var name = cm.getDataIndex(i);
cs[i] = {
name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
renderer : cm.getRenderer(i),
id : cm.getColumnId(i),
style : this.getColumnStyle(i),
editor : cm.getCellEditor(i, 0)
//,cm: cm
};
}
return cs;
}
});
Ext.util.Format.comboboxRenderer = function(value){
var editor = this.editor;
if(editor){
var field = editor.field;
if(field && field.findRecord && field.valueField) {
if((typeof value.indexOf === 'function') && value.indexOf(',') != -1){
// we have a lovcombo with several options selected
var keys = value.split(',');
var values = [];
Ext.each(keys, function(key){
var rec = field.findRecord(field.valueField, key);
if(rec){
values.push(rec.data[field.displayField]);
}
});
return values.join(', ');
}else{
var rec = field.findRecord(field.valueField, value);
if(rec){
return rec.data[field.displayField];
}
}
}
}
return value;
};
原理就是:
1.覆盖Ext原生的Ext.grid.GridView,把editor附加到renderer上,
2. 添加一个Ext.util.Format.comboboxRenderer,在配置时renderer指定为这个,修改后的代码为:
dataColumnModel = new Ext.grid.ColumnModel([
{
header: 'Party',
dataIndex: 'IDparty',
width: 150,
editor: new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
store:new Ext.data.SimpleStore({
fields:['partyValue', 'partyName'],
data: [['1','No Party'],['2','Federalist'],['3','Democratic-Republican'],['4','Democratic'],['5','Whig'],['6','Republican']]
}),
mode: 'local',
displayField: 'partyName',
valueField: 'partyValue',
listClass: 'x-combo-list-small'
})
,renderer: Ext.util.Format.comboboxRenderer
}
]);
如果要更个性化的定制,也可以直接在renderer里访问editor了,如:
,renderer: function(value, metadata, record, rowIndex, colIndex, store){
console.log(this.editor);
// 具体访问data数据方法见Ext.util.Format.comboboxRenderer代码
return value;
}