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

Angular Ag Grid实现选中行按选择顺序显示序号徽章

解决方案

一、实现选中行按选择顺序显示序号徽章

要实现按选中顺序显示序号,核心是维护一个记录选中行顺序的数组,在选中状态变更时更新该数组,再让单元格渲染器根据数组计算当前行的序号。

1. 父组件配置与选中事件处理

在承载Ag Grid的父组件中,定义数组存储选中行的唯一标识(如id),并监听selectionChanged事件更新顺序:

import { Component } from '@angular/core';
import { AgGridAngular } from 'ag-grid-angular';
import { NameCellRendererComponent } from './name-cell-renderer.component';

@Component({
  selector: 'app-my-grid',
  template: `
    <ag-grid-angular
      style="width: 100%; height: 500px;"
      [rowData]="rowData"
      [columnDefs]="columnDefs"
      [rowSelection]="'multiple'"
      (selectionChanged)="onSelectionChanged($event)"
      [frameworkComponents]="frameworkComponents"
    ></ag-grid-angular>
  `
})
export class MyGridComponent {
  // 示例行数据,需包含唯一标识id
  rowData = [
    { id: 1, name: 'Alice', age: 30 },
    { id: 2, name: 'Bob', age: 25 },
    { id: 3, name: 'Charlie', age: 35 }
  ];

  columnDefs = [
    { 
      headerName: 'Name', 
      field: 'name', 
      cellRendererFramework: NameCellRendererComponent,
      // 将选中顺序数组传递给渲染器
      cellRendererParams: { selectedOrder: this.selectedOrder }
    },
    { headerName: 'Age', field: 'age' },
    // 复选框列
    { headerName: '', field: 'select', checkboxSelection: true, headerCheckboxSelection: true }
  ];

  frameworkComponents = { nameCellRenderer: NameCellRendererComponent };
  // 存储选中行的id,按选中顺序排列
  selectedOrder: number[] = [];

  onSelectionChanged(event: any) {
    const selectedNodes = event.api.getSelectedNodes();
    const selectedIds = selectedNodes.map(node => node.data.id);

    // 更新选中顺序:保留已选中的,添加新选中的,移除取消选中的
    this.selectedOrder = this.selectedOrder.filter(id => selectedIds.includes(id));
    selectedIds.forEach(id => {
      if (!this.selectedOrder.includes(id)) {
        this.selectedOrder.push(id);
      }
    });

    // 触发Name列单元格刷新,更新序号徽章
    event.api.refreshCells({ columns: ['name'] });
  }
}

2. 单元格渲染器组件实现

在自定义的NameCellRendererComponent中,根据传递的selectedOrder数组计算当前行的序号:

import { Component } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';

@Component({
  template: `
    <div class="name-cell">
      {{ params.value }}
      <!-- 仅当行被选中时显示序号徽章 -->
      <span *ngIf="order" class="order-badge">{{ order }}</span>
    </div>
  `,
  styles: [`
    .name-cell { display: flex; align-items: center; }
    .order-badge {
      margin-left: 8px;
      padding: 2px 6px;
      background-color: #2196F3;
      color: white;
      border-radius: 12px;
      font-size: 12px;
    }
  `]
})
export class NameCellRendererComponent implements ICellRendererAngularComp {
  params: any;
  order?: number;

  agInit(params: any): void {
    this.params = params;
    this.calculateOrder();
  }

  // 单元格刷新时重新计算序号
  refresh(params: any): boolean {
    this.params = params;
    this.calculateOrder();
    return true;
  }

  private calculateOrder() {
    const rowId = this.params.data.id;
    const index = this.params.selectedOrder.indexOf(rowId);
    // 序号从1开始计数
    this.order = index !== -1 ? index + 1 : undefined;
  }
}

二、在cellRendererFramework中获取行选中事件

有两种常用方式在自定义单元格渲染器中监听行选中状态变化:

1. 直接监听Ag Grid的selectionChanged事件

利用Ag Grid API提供的事件监听能力,在渲染器组件中订阅selectionChanged事件,同时注意在组件销毁时取消订阅避免内存泄漏:

import { Component, OnDestroy } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { Subscription } from 'rxjs';

@Component({
  // 模板同之前的渲染器
})
export class NameCellRendererComponent implements ICellRendererAngularComp, OnDestroy {
  params: any;
  order?: number;
  private selectionSub?: Subscription;

  agInit(params: any): void {
    this.params = params;
    this.calculateOrder();

    // 监听选中状态变更事件
    this.selectionSub = params.api.addEventListener('selectionChanged', () => {
      const isSelected = this.params.node.isSelected();
      // 这里可以处理选中/取消选中的逻辑
      console.log(`行${this.params.data.id}选中状态: ${isSelected}`);
      this.calculateOrder();
    });
  }

  refresh(params: any): boolean {
    this.params = params;
    this.calculateOrder();
    return true;
  }

  private calculateOrder() {
    const rowId = this.params.data.id;
    const index = this.params.selectedOrder.indexOf(rowId);
    this.order = index !== -1 ? index + 1 : undefined;
  }

  ngOnDestroy(): void {
    // 销毁订阅,防止内存泄漏
    this.selectionSub?.unsubscribe();
  }
}

2. 通过父组件传递状态变更触发刷新

如第一部分示例中,父组件在selectionChanged事件中调用refreshCells,渲染器通过refresh方法接收更新,这种方式更轻量,适合只需要根据选中状态更新UI的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:01:05