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
相关产品推荐
相关产品推荐

