这就是我的做法:
Ext.define('Ext.form.field.EmptyableComboBox', {
extend: 'Ext.form.field.ComboBox',
xtype: 'emptyable_combobox',
uses: [ 'Ext.view.BoundList' ],
/** The source is used to hold the original store. */
_source: null,
editable: false, // must pick from an item in the list
allowBlank: true, // obviously can't be required, as the user can reset to blank.
initComponent: function() {
this._source = this.getStore();
var newData = [
this._toEntry(null, null)
];
this._source.each(function(record) {
newData.push(this._toEntry(record.get(this.valueField), record.get(this.displayField)));
}, this)
this.store = new Ext.data.Store({
fields: [ this.valueField, this.displayField ],
data: newData
});
var itemCls = Ext.view.BoundList.prototype.itemCls;
var innerTpl = Ext.view.BoundList.prototype.getInnerTpl;
this.listConfig = Ext.apply({
tpl: new Ext.XTemplate(
'<ul class="' + Ext.plainListCls + '">',
'<tpl for=".">',
'<li role="option" unselectable="on" class="' + itemCls + '">',
'<tpl if="name == null">',
'<em>' + this.emptyText + '</em>',
'<tpl else>',
innerTpl(this.displayField),
'</tpl>',
'</li>',
'<tpl if="name == null">',
'<hr />',
'</tpl>',
'</tpl>',
'</ul>'
)
}, this.listConfig);
this.callParent(arguments);
},
_toEntry: function(value, display) {
var result = {}
result[this.valueField] = value;
result[this.displayField] = display;
return result;
}
})
如果您需要在原始商店中支持过滤,则需要做一些更复杂的事情,但这应该会为您指明正确的方向。
请注意,如果您的 ComboBox 是 editable(例如,您允许用户输入它),他们可以通过清除文本来简单地输入空值。这就是为什么此实现将 editable 值硬编码为 false。