ExtJS 5.1:Select 多个不相邻的网格单元格

ExtJS 5.1: Select multiple non-adjacent grid cells

我正在尝试 select 多个单元格使用 spreadsheet model, but it doesn't look like there's a method to select an individual cell or bunch of cells that aren't a range. (I also tried the cellmodel, but that doesn't look like it works either.) I know selectCells exists, but like I said, I could potentially be selecting a bunch of cells that aren't in a range. Here's an example (and Fiddle):

Ext.application({
  name: 'Fiddle',

  launch: function() {
    var store = Ext.create('Ext.data.Store', {
      fields: ['time', 'days'],
      proxy: {
        type: 'memory'
      },
      data: [{
        time: 800,
        days: [{
          day: 'Monday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Tuesday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Wednesday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Thursday'
        }, {
          day: 'Friday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Saturday',
          nameId: 3,
          name: 'Skinner'
        }, {
          day: 'Sunday',
          nameId: 2,
          name: 'Scully'
        }]
      }]
    });
    var renderFn = function(value, metaData, record, rowIdx, colIdx, store, view) {
      var days = record.get('days');
      if (days) {
        var column = days[colIdx - 2];
        if (column && column.nameId !== undefined) {
          metaData.tdCls = 'my-attr-' + (column.nameId % 10);
        }
      }
      return;
    };
    var onSelectionChange = function(grid, selection, eOpts) {
      var store = grid.getStore();
      if (selection && selection.startCell) {
        var colIdx = selection.startCell.colIdx;
        var days = selection.startCell.record.get('days');
        if (days && store) {
          var day = days[colIdx - 2];
          var selectionModel = this.getSelectionModel();
          if (day && selectionModel) {
            nameId = day.nameId;
            if (nameId !== undefined) {
              var items = [];
              store.each(function(rec, rowIdx) {
                var recDays = rec.get('days');
                if (recDays) {
                  for (var i = 0; i < recDays.length; i++) {
                    var rec = recDays[i];
                    if (rec && rec.nameId === nameId) {
                      items.push([rowIdx, i + 2]);
                    }
                  }
                }
              }, this);
              console.log(items);
              //                            selectionModel.select(items);
            }
          }
        }
      }
    };
    /*var onSelectionChangeGrid = function(selModel, record, rowIdx, colIdx, eOpts) {
        var days = record.get('days');
        var store = this.getStore();
        console.log(days, store);
        if (days && store) {
            var day = days[colIdx - 2];
            var selectionModel = this.getSelectionModel();
            if (day && selectionModel) {
                nameId = day.nameId;
                if (nameId !== undefined) {
                    var items = [];
                    store.each(function(rec) {
                        var recDays = rec.get('days');
                        if (recDays) {
                            for (var i = 0; i < recDays.length; i++) {
                                var rec = recDays[i];
                                if (rec && rec.nameId === nameId) {
                                    items.push(rec);
                                }
                            }
                        }
                    }, this);
                    console.log(items);
                    selectionModel.select(items);
                }
            }
        }
    };*/
    var grid = Ext.create('Ext.grid.Panel', {
      store: store,
      forceFit: true,
      selModel: {
        selType: 'spreadsheet',
        mode: 'multi'
      },
      columns: [{
        text: 'Time',
        dataIndex: 'time'
      }, {
        text: 'Monday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Tuesday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Wednesday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Thursday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Friday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Saturday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Sunday',
        dataIndex: 'days',
        renderer: renderFn
      }],
      renderTo: Ext.getBody()
    });
    grid.on('selectionchange', onSelectionChange, grid);
  }
});

我想要发生的是,当我 select 第一个黄色单元格时,它 select 是另一个黄色单元格,如果我 select 一个黑色单元格,它selects 其他黑色单元格。在我的代码中,我有一个数组数组,其中包含相同颜色的每个单元格的 rowIdx 和 colIdx,但我不知道如何使用此信息,因为没有可用的方法。

我已经开始深入研究代码以了解它们是如何处理范围 selection 的,但看起来它是 Row 和 Cell selection 的组合。它看起来也不像我可以使用 "ctrl" 到 select 多个单元格,即使我确实将模式设置为 multi... 根据 API:

"MULTI" - Allows complex selection of multiple items using Ctrl and Shift keys.

有人对如何开始这件事有任何想法或指导吗?

我能够解决这个问题并且也使用了 cellmodel!它仍然是一个非常 hacky 的解决方案并且感觉不对,因为我正在设置自己的 selections/using 处理程序和私有方法,但就像我说的那样,它有效。这是代码(和 Fiddle):

Ext.application({
  name: 'Fiddle',

  launch: function() {
    var store = Ext.create('Ext.data.Store', {
      fields: ['time', 'days'],
      proxy: {
        type: 'memory'
      },
      data: [{
        time: 800,
        days: [{
          day: 'Monday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Tuesday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Wednesday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Thursday'
        }, {
          day: 'Friday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Saturday',
          nameId: 3,
          name: 'Skinner'
        }, {
          day: 'Sunday',
          nameId: 2,
          name: 'Scully'
        }]
      }, {
        time: 830,
        days: [{
          day: 'Monday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Tuesday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Wednesday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Thursday'
        }, {
          day: 'Friday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Saturday',
          nameId: 3,
          name: 'Skinner'
        }, {
          day: 'Sunday',
          nameId: 2,
          name: 'Scully'
        }]
      }, {
        time: 900,
        days: [{
          day: 'Monday'
        }, {
          day: 'Tuesday'
        }, {
          day: 'Wednesday',
          nameId: 1,
          name: 'Mulder'
        }, {
          day: 'Thursday',
          nameId: 2,
          name: 'Scully'
        }, {
          day: 'Friday',
          nameId: 4,
          name: 'Lone Gunmen'
        }, {
          day: 'Saturday'
        }, {
          day: 'Sunday'
        }]
      }, {
        time: 930,
        days: [{
          day: 'Monday'
        }, {
          day: 'Tuesday'
        }, {
          day: 'Wednesday',
          nameId: 5,
          name: 'Smoking Man'
        }, {
          day: 'Thursday',
          nameId: 5,
          name: 'Smoking Man'
        }, {
          day: 'Friday'
        }, {
          day: 'Saturday',
          nameId: 4,
          name: 'Lone Gunmen'
        }, {
          day: 'Sunday'
        }]
      }]
    });
    var renderFn = function(value, metaData, record, rowIdx, colIdx, store, view) {
      var days = record.get('days');
      if (days) {
        var column = days[colIdx - 1];
        if (column && column.nameId !== undefined) {
          metaData.tdCls = 'my-attr-' + (column.nameId % 10);
        }
      }
      return;
    };
    var onSelectionChange = function(selectionModel, record, rowIdx, colIdx, eOpts) {
      var store = this.getStore();
      console.log('here', record);
      if (record) {
        var view = this.view;
        var days = record.get('days');
        if (view && days && store) {
          var cell = Ext.create('Ext.grid.CellContext', view);
          // Subtract 1 because we have to compensate for the time column
          var day = days[colIdx - 1];
          if (day && selectionModel && cell) {
            grid.deselectCells();
            var nameId = day.nameId;
            if (nameId !== undefined) {
              var items = [];
              store.each(function(rec, rowIdx) {
                var recDays = rec.get('days');
                if (recDays) {
                  for (var i = 0; i < recDays.length; i++) {
                    var rec = recDays[i];
                    if (rec && rec.nameId === nameId) {
                      grid.selectedCells.push([rowIdx, i + 1]);
                      cell.setPosition(rowIdx, i + 1);
                      view.onCellSelect(cell);
                    }
                  }
                }
              }, this);
            }
          }
        }
      }
    };
    var grid = Ext.create('Ext.grid.Panel', {
      store: store,
      forceFit: true,
      selModel: {
        selType: 'cellmodel'
      },
      viewConfig: {
        columnLines: false
      },
      selectedCells: [],
      columns: [{
        text: 'Time',
        dataIndex: 'time'
      }, {
        text: 'Monday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Tuesday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Wednesday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Thursday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Friday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Saturday',
        dataIndex: 'days',
        renderer: renderFn
      }, {
        text: 'Sunday',
        dataIndex: 'days',
        renderer: renderFn
      }],
      deselectCells: function() {
        var grid = this;
        var selectedCells = this.getSelectedCells();
        if (grid && selectedCells && selectedCells.length) {
          var view = grid.view;
          var cell = Ext.create('Ext.grid.CellContext', view);
          for (var i = 0; i < selectedCells.length; i++) {
            var selection = selectedCells[i];
            if (selection) {
              cell.setPosition({
                row: selection[0],
                column: selection[1]
              });
              view.onCellDeselect(cell);
            }
          }
        }
        this.selectedCells = [];
      },
      getSelectedCells: function() {
        var selectedCells = this.selectedCells;
        return selectedCells;
      },
      renderTo: Ext.getBody()
    });
    grid.on('select', onSelectionChange, grid);
  }
});