Ext JS 6.6.0:为ComboBox添加Spinner(上下箭头)功能
Ext JS 6.6.0 给ComboBox添加Spinner上下箭头实现方案
核心思路
通过继承Ext.form.field.ComboBox自定义组件,保留原有所有功能的同时,添加上下箭头Spinner元素并绑定遍历下拉选项的逻辑,这是最贴合Ext JS组件扩展机制的方案。
实现步骤及代码
1. 自定义带Spinner的ComboBox组件
Ext.define('MyApp.form.field.ComboBoxWithSpinner', { extend: 'Ext.form.field.ComboBox', alias: 'widget.comboboxwithspinner', initComponent: function() { this.callParent(arguments); // 创建Spinner容器,嵌入到ComboBox内部 const spinnerCt = Ext.DomHelper.append(this.bodyEl, { cls: 'combo-spinner-ct' }, true); // 创建上箭头按钮 this.upBtn = Ext.DomHelper.append(spinnerCt, { cls: 'combo-spinner-btn combo-spinner-up', html: '▲' }, true); // 创建下箭头按钮 this.downBtn = Ext.DomHelper.append(spinnerCt, { cls: 'combo-spinner-btn combo-spinner-down', html: '▼' }, true); // 绑定箭头点击事件 this.upBtn.on('click', this.onUpClick, this); this.downBtn.on('click', this.onDownClick, this); // 监听store加载、选中项变化,同步按钮状态 this.mon(this.getStore(), 'load', this.updateSpinnerState, this); this.on('select', this.updateSpinnerState, this); }, // 上箭头逻辑:选中当前项的下一项 onUpClick: function() { const store = this.getStore(); const currentRecord = this.getSelection()[0]; const currentIndex = currentRecord ? store.indexOf(currentRecord) : -1; if (currentIndex < store.getCount() - 1) { const nextRecord = store.getAt(currentIndex + 1); this.select(nextRecord); } }, // 下箭头逻辑:选中当前项的上一项;无选中项时选最后一项 onDownClick: function() { const store = this.getStore(); const currentRecord = this.getSelection()[0]; const currentIndex = currentRecord ? store.indexOf(currentRecord) : 0; if (currentIndex > 0) { const prevRecord = store.getAt(currentIndex - 1); this.select(prevRecord); } else if (store.getCount() > 0) { this.select(store.getAt(store.getCount() - 1)); } }, // 更新按钮禁用/启用状态 updateSpinnerState: function() { const store = this.getStore(); const count = store.getCount(); const currentRecord = this.getSelection()[0]; const currentIndex = currentRecord ? store.indexOf(currentRecord) : -1; this.upBtn.setDisabled(currentIndex === count - 1 || count === 0); this.downBtn.setDisabled(currentIndex === 0 || count === 0); }, // 组件销毁时清理事件绑定 onDestroy: function() { this.upBtn.un('click', this.onUpClick, this); this.downBtn.un('click', this.onDownClick, this); this.callParent(arguments); } });
2. 添加CSS样式(让Spinner正确显示)
/* Spinner容器定位:避开默认下拉箭头 */ .combo-spinner-ct { position: absolute; right: 24px; top: 0; height: 100%; display: flex; flex-direction: column; justify-content: space-between; padding: 2px 0; box-sizing: border-box; } /* 箭头按钮基础样式 */ .combo-spinner-btn { width: 16px; height: 50%; text-align: center; line-height: 1; cursor: pointer; color: #666; font-size: 10px; background-color: #f5f5f5; border-left: 1px solid #ddd; user-select: none; } /* 鼠标 hover 效果 */ .combo-spinner-btn:hover { background-color: #e8e8e8; } /* 禁用状态样式 */ .combo-spinner-btn[disabled] { cursor: not-allowed; opacity: 0.5; }
3. 组件使用示例
和普通ComboBox的配置完全一致,直接使用自定义的xtype即可:
Ext.create('Ext.form.Panel', { renderTo: Ext.getBody(), items: [{ xtype: 'comboboxwithspinner', fieldLabel: '选择项', store: Ext.create('Ext.data.Store', { fields: ['id', 'text'], data: [ {id: 1, text: '选项1'}, {id: 2, text: '选项2'}, {id: 3, text: '选项3'} ] }), valueField: 'id', displayField: 'text', queryMode: 'local', editable: true // 保留原有的可编辑过滤功能 }] });
注意事项
- 保留了ComboBox的所有原生功能:下拉选择、输入过滤、事件监听等。
- 支持远程加载的store:会自动在store加载完成后更新Spinner状态。
- 样式可根据需求调整:比如箭头图标、位置、颜色等。
内容的提问来源于stack exchange,提问作者StSch
相关产品推荐
相关产品推荐

