如何在 Angular-Slickgrid 中同时启用行选择与单元格多选功能

6次阅读

如何在 Angular-Slickgrid 中同时启用行选择与单元格多选功能

本文介绍在 angular-slickgrid 中实现 excel 风格的混合选择模式:点击行号列切换为行选择,其余区域保持单元格多选,通过动态切换 slickgrid 选择模型并调用 invalidate() 实现无缝切换。

Angular-Slickgrid 默认采用互斥的选择模型——启用 enableRowSelection 会禁用单元格级操作,而开启 enableexcelCopyBuffer(隐式启用 SlickCellSelectionModel)则仅支持单元格/区域选择。但实际业务中常需类似 Excel 的交互体验:单击行号(如左侧索引列)选中整行,点击数据区域则进行多单元格编辑或复制。这一需求无法通过配置项直接满足,需手动干预 SlickGrid 底层选择模型。

核心思路是:引入一个固定索引列(如序号列),监听其点击事件,动态切换 SelectionModel 实例,并强制重绘网格以应用变更。关键步骤如下:

  1. 禁用自动行选择配置:移除 enableRowSelection: true,避免与单元格选择冲突;
  2. 启用单元格导航与复制缓冲:设置 enableCellNavigation: true 和 enableExcelCopyBuffer: true;
  3. 定义索引列:在 columnDefinitions 中添加首列为 id: ‘#’,formatter: Formatters.rowNumber 或自定义序号渲染;
  4. 绑定全局点击处理器:使用 (onClick) 输出事件,在 args.cell === 0(即点击第一列)时切换为 SlickRowSelectionModel,否则切回 SlickCellSelectionModel;
  5. 触发视图更新:每次切换后必须调用 slickGrid.invalidate(),否则 ui 不响应。

以下是完整可运行的代码示例:

import { Component, OnInit } from '@angular/core'; import {   AngularGridInstance,   GridOption,   Formatters,   SlickCellSelectionModel,   SlickRowSelectionModel } from 'angular-slickgrid';  @Component({   selector: 'app-grid',   template: `   ` }) export class GridComponent implements OnInit {   angularGrid!: AngularGridInstance;   gridOptions!: GridOption;   columnDefinitions = [     {       id: '#',       name: '#',       field: 'rowindex',       width: 40,       resizable: false,       sortable: false,       formatter: Formatters.rowNumber,       excludeFromExport: true,       excludeFromColumnPicker: true,       excludeFromGridMenu: true     },     { id: 'name', name: 'Name', field: 'name' },     { id: 'age', name: 'Age', field: 'age' }   ];   dataset = [     { name: 'Alice', age: 28 },     { name: 'Bob', age: 32 },     { name: 'Charlie', age: 25 }   ];    ngonInit(): void {     this.gridOptions = {       enableCellNavigation: true,       enableExcelCopyBuffer: true,       autoResize: { containerId: 'grid-container', sidePadding: 15 }     };   }    angularGridReady(grid: AngularGridInstance) {     this.angularGrid = grid;   }    onClick(event: Event, args: any) {     // 假设索引列为第0列(即'#'列)     if (args.cell === 0) {       // 点击索引列 → 切换为行选择       if (!(this.angularGrid.slickGrid.getSelectionModel() instanceof SlickRowSelectionModel)) {         this.angularGrid.slickGrid.setSelectionModel(new SlickRowSelectionModel());         this.angularGrid.slickGrid.invalidate();       }     } else {       // 点击其他列 → 切换为单元格选择       if (!(this.angularGrid.slickGrid.getSelectionModel() instanceof SlickCellSelectionModel)) {         this.angularGrid.slickGrid.setSelectionModel(new SlickCellSelectionModel());         this.angularGrid.slickGrid.invalidate();       }     }   } }

⚠️ 注意事项

  • invalidate() 仅刷新视图,不重置已选内容。若需清除上一模式的选中状态,可在切换前调用 clearSelection();
  • 行选择模式下 getSelectedRows() 返回行索引数组,单元格模式下需通过 getSelectedRanges() 获取矩形区域;
  • 若使用 rowSelectionOptions.selectableOverride 自定义行可选逻辑,需确保其与切换逻辑兼容;
  • 此方案依赖 SlickGrid 原生 API,升级 Angular-Slickgrid 版本时请验证 SlickCellSelectionModel / SlickRowSelectionModel 类路径是否变更(v7+ 中位于 @slickgrid-universal/common 包内)。

通过该方案,你既能享受 Excel 式的高效行操作,又不失精细的单元格编辑能力,真正实现“按需选择、一触切换”的专业表格体验。

text=ZqhQzanResources