Ext JS:MultiSelect ComboBox在取消选择行为之前

时间:2014-05-29 18:19:38

标签: extjs combobox extjs4 multi-select

我有一个将multiSelect作为true的ComboBox。此ComboBox具有初始值集,在打开ComboBox时会选择该值。当我想使用ComboBox.setValue时,问题就出现了...使用此函数显然会触发 beforedeselect 事件,但不会触发select事件。奇怪的是, beforedeselect 仅针对我在 setValue 中设置的值触发。

请参阅this example

要重现此问题,您可以执行以下操作:

  1. 点击“设置组合框值”按钮
  2. 点击下拉列表
  3. 然后你应该看到4个警报:马里兰州,宾夕法尼亚州,马里兰州,宾夕法尼亚州
    1. 点击下拉列表
    2. 然后你应该看到2个警报:科罗拉多州科罗拉多州
    3. 点击“设置组合框值”按钮
    4. 你应该看到1个警告:科罗拉多
    5. 再次点击“设置组合框值”按钮
    6. 您应该看到2个提醒:马里兰州,宾夕法尼亚州
    7. 也许我误解了这个事件,但为什么这是行为呢?为什么使用setValue从ComboBox中取消选择状态(我正在设置),但是当我打开ComboBox时仍然选择它们?为什么第一个测试用例会显示4个警报?

      更新

      查看syncSelection代码,看起来在选择模型上调用deselectAll,这可以解释为什么调用 beforedeselect 事件,但选择模型然后调用select .. 。这没有解释为什么没有调用选择事件。

      Ext.onReady(function() {
          var store = Ext.create('Ext.data.Store', {
              fields: ['state_id', 'state_name'],
              data: [
                  {state_id: 1, state_name: 'Colorado'},
                  {state_id: 2, state_name: 'Maryland'},
                  {state_id: 3, state_name: 'Pennsylvania'}
              ]
          });
          var combo = Ext.create('Ext.form.field.ComboBox', {
              valueField: 'state_id',
              displayField: 'state_name',
              store: store,
              multiSelect: true,
              value: [1],
              listeners: {
                  beforedeselect: function(combo, record, index, eOpts) {
                      alert('deselected: ' + record.get('state_name'));
                  },
                  beforeselect: function() {
                      alert('selected');
                  }
              },
              renderTo: Ext.getBody()
          });
          var button = Ext.create('Ext.button.Button', {
              text: 'Set ComboBox Value',
              listeners: {
                  click: function() {
                      combo.setValue([2, 3]);
                  }
              },
              renderTo: Ext.getBody()
          });
      });
      
      来自Sencha论坛的

      Cross-post

1 个答案:

答案 0 :(得分:0)

我想出了一个解决方案,但我不确定其影响......到目前为止,我还没有看到任何影响。我用以下内容覆盖了comboBox的 syncSelection 方法:

syncSelection: function() {
    var me = this,
        picker = me.picker,
        selection, selModel,
        values = me.valueModels || [],
        vLen  = values.length, v, value;

    if (picker) {
      // From the value, find the Models that are in the store's current data
      selection = [];
      for (v = 0; v < vLen; v++) {
        value = values[v];

        if (value && value.isModel && me.store.indexOf(value) >= 0) {
          selection.push(value);
        }
      }

      // Update the selection to match
      me.ignoreSelection++;
      selModel = picker.getSelectionModel();
      selModel.deselectAll(true);  // This is the key to it all... suppressing the event listener, just like what's happening in the select right below this
      if (selection.length) {
        selModel.select(selection, undefined, true);
      }
      me.ignoreSelection--;
    }
  }

唯一的变化是 deselectAll 调用...它现在正在禁止触发的取消选择事件,就像之后的选择事件一样......我很想知道他们为什么不这样做t像在select中一样压制事件。就像我说的那样,我不确定会产生什么影响,但到目前为止它给了我很大的里程。