You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ng-bootstrap table中使用SHIFT键选择连续行范围?

在ng-bootstrap Table中实现SHIFT键连续选行(同react-data-grid逻辑)

核心思路

要实现和react-data-grid一致的SHIFT连续选行逻辑,核心是记录上次单独选中的行,当按住SHIFT点击新行时,计算两行之间的索引范围,批量选中该范围内的所有行。

具体实现步骤

1. 定义组件关键状态

在Angular组件中维护三个核心状态:

  • selectedRows: any[] = []:存储所有已选中的行数据
  • lastClickedRow: {row: any, index: number} | null = null:记录上次非SHIFT辅助下选中的行及其索引
  • isShiftPressed: boolean = false:标记当前是否按住SHIFT键

2. 监听SHIFT键状态

通过全局键盘事件捕获SHIFT键的按下与松开:

@Component({
  // 组件元数据(如selector、templateUrl等)
  host: {
    '(document:keydown.shift)': 'onShiftDown($event)',
    '(document:keyup.shift)': 'onShiftUp($event)',
  }
})
export class YourTableComponent {
  // ...其他状态与方法

  onShiftDown(event: KeyboardEvent) {
    this.isShiftPressed = true;
  }

  onShiftUp(event: KeyboardEvent) {
    this.isShiftPressed = false;
  }
}

3. 绑定行点击事件并处理逻辑

在ng-bootstrap table的行模板上绑定点击事件,根据SHIFT状态执行不同选中逻辑:

<ngb-table [data]="tableData">
  <!-- 列定义 -->
  <ng-template ngbHeaderCellDef *ngFor="let col of columns">{{ col.name }}</ng-template>
  <ng-template ngbCellDef let-row let-index="index" *ngFor="let col of columns">
    {{ row[col.field] }}
  </ng-template>

  <!-- 行模板:绑定点击事件与选中样式 -->
  <ng-template ngbRowDef let-row let-index="index" [ngbRowDef]="columns"
    [class.selected]="isRowSelected(row)"
    (click)="onRowClick(row, index)">
  </ng-template>
</ngb-table>

对应的组件处理方法:

onRowClick(row: any, index: number) {
  if (!this.isShiftPressed) {
    // 普通点击:切换当前行选中状态,更新上次选中记录
    const existingIdx = this.selectedRows.findIndex(r => r.id === row.id);
    if (existingIdx > -1) {
      this.selectedRows.splice(existingIdx, 1);
      this.lastClickedRow = null;
    } else {
      this.selectedRows = [row];
      this.lastClickedRow = { row, index };
    }
  } else {
    // SHIFT点击:计算连续范围并批量选中
    if (!this.lastClickedRow) {
      this.selectedRows = [row];
      this.lastClickedRow = { row, index };
      return;
    }

    // 确定范围的起始与结束索引
    const startIdx = Math.min(this.lastClickedRow.index, index);
    const endIdx = Math.max(this.lastClickedRow.index, index);
    
    // 选中区间内的所有行
    this.selectedRows = this.tableData.slice(startIdx, endIdx + 1);
  }
}

// 辅助方法:判断行是否已选中
isRowSelected(row: any): boolean {
  return this.selectedRows.some(r => r.id === row.id);
}

4. 添加选中行样式

在组件CSS中定义选中行的视觉样式,提升用户体验:

.selected {
  background-color: #e3f2fd; /* 可根据需求自定义背景色 */
}

关键逻辑说明

  • 普通点击时,要么切换当前行的选中状态,要么单独选中该行,并更新lastClickedRow为当前行的信息。
  • SHIFT点击时,基于lastClickedRow的索引计算连续区间,确保选中从上次选中行到当前点击行的所有行,和react-data-grid的行为完全匹配。
  • 键盘事件绑定到document上,确保即使焦点不在表格内,SHIFT键的状态也能被正确捕获。

内容的提问来源于stack exchange,提问作者user2038596

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:40:05