【问题标题】:What is the cleanest way to have "Empty" option in a combobox in Extjs6?在 Extjs6 的组合框中有“空”选项的最干净的方法是什么?
【发布时间】:2016-03-15 20:33:05
【问题描述】:

我有一个由 ajax 商店支持的基本组合框。我希望能够从组合中选择一个空值作为选项(它不作为商店中的记录存在)。设置emptyText: 'None' 会很完美,唯一的问题是一旦你选择了某个值,你就不能再选择一个空的了。

有没有比监听存储负载和注入额外的空记录或类似的东西更好的选择。我不想在该商店中永久保留空记录,仅在某些组合框中使用时。

{
    xtype: 'combo',
    queryMode: 'local',
    triggerAction: 'all',
    forceSelection: true,
    editable: false,
    emptyText: 'None',
    store: 'MyStore',
}

【问题讨论】:

    标签: extjs extjs6


    【解决方案1】:

    我通过创建一个插件来实现这一点。

    Ext.define("App.ux.plugin.form.field.EmptiableComboBox", {
        extend : 'Ext.AbstractPlugin',
        alias : 'plugin.emptiableCombo',
        init : function(combo) {
            this.combo = combo;
            this.callParent();
            combo.addListener('change', function() {
                if (this.getValue() === null || this.getValue() == '') {
                    this.reset();
                    this.setRawValue(null);
                    this.lastSelection = [];
                }
            });
        }
    });
    

    这是我的使用方法。

    {   
        type:'combobox',
        typeAhead:true,
        plugins: ['emptiableCombo'],
        listConfig:{
            cls:'x-combo-boundlist-small'
        }
    }
    

    更新: 我之前已经完成了这个练习,并且肯定我们不想添加一个空值选项。所以我们有两个选择

    1. 为可清空的 Combo 添加清除触发器。
    2. 使 Combobox 可编辑并启用 forceSelection,这样用户可以轻松输入值进行自动选择,并且如果该字段是可选的,他可以清除这些值。启用 forceSelection 后,用户无法输入任意值。

    我们选择了选项 2 并创建了这个插件。如果您想出任何其他更好的解决方案,请在此处发布。谢谢。

    【讨论】:

    【解决方案2】:

    这就是我的做法:

    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。

    【讨论】:

      猜你喜欢
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多