Angular-PrimeNg两表格间行迁移功能实现方案咨询
Angular实现带复选框的左右表格行迁移(类似R Shiny多项目移动)
你可以直接用PrimeNG的<p-table>和<p-tableCheckbox>配合自定义逻辑实现,不需要额外组件,以下是完整实现方案:
组件类代码(.ts)
import { Component } from '@angular/core'; interface Item { id: number; name: string; description: string; } @Component({ selector: 'app-table-migration', templateUrl: './table-migration.component.html' }) export class TableMigrationComponent { // 左表格数据源 leftData: Item[] = [ { id: 1, name: '项目1', description: '描述1' }, { id: 2, name: '项目2', description: '描述2' }, { id: 3, name: '项目3', description: '描述3' }, { id: 4, name: '项目4', description: '描述4' } ]; // 右表格数据源 rightData: Item[] = []; // 左表格选中项 leftSelection: Item[] = []; // 右表格选中项 rightSelection: Item[] = []; // 左到右单条迁移 moveSingleToRight(): void { if (this.leftSelection.length !== 1) return; const selectedItem = this.leftSelection[0]; // 从左表移除 this.leftData = this.leftData.filter(item => item.id !== selectedItem.id); // 添加到右表 this.rightData.push(selectedItem); // 清空选中状态 this.leftSelection = []; } // 左到右全部选中迁移 moveAllToRight(): void { if (this.leftSelection.length === 0) return; // 将选中项添加到右表 this.rightData = [...this.rightData, ...this.leftSelection]; // 从左表移除选中项 this.leftData = this.leftData.filter(item => !this.leftSelection.some(s => s.id === item.id)); // 清空选中状态 this.leftSelection = []; } // 右到左单条迁移 moveSingleToLeft(): void { if (this.rightSelection.length !== 1) return; const selectedItem = this.rightSelection[0]; this.rightData = this.rightData.filter(item => item.id !== selectedItem.id); this.leftData.push(selectedItem); this.rightSelection = []; } // 右到左全部选中迁移 moveAllToLeft(): void { if (this.rightSelection.length === 0) return; this.leftData = [...this.leftData, ...this.rightSelection]; this.rightData = this.rightData.filter(item => !this.rightSelection.some(s => s.id === item.id)); this.rightSelection = []; } }
模板代码(.html)
<div class="flex gap-4 items-center"> <!-- 左表格 --> <p-table [value]="leftData" [(selection)]="leftSelection" selectionMode="multiple" styleClass="w-64"> <ng-template pTemplate="header"> <tr> <th> <p-tableCheckbox></p-tableCheckbox> </th> <th>名称</th> <th>描述</th> </tr> </ng-template> <ng-template pTemplate="body" let-item> <tr [pSelectableRow]="item"> <td> <p-tableCheckbox [value]="item"></p-tableCheckbox> </td> <td>{{ item.name }}</td> <td>{{ item.description }}</td> </tr> </ng-template> </p-table> <!-- 迁移按钮组 --> <div class="flex flex-col gap-2"> <button pButton label=">" (click)="moveSingleToRight()" [disabled]="leftSelection.length !== 1"></button> <button pButton label=">>" (click)="moveAllToRight()" [disabled]="leftSelection.length === 0"></button> <button pButton label="<" (click)="moveSingleToLeft()" [disabled]="rightSelection.length !== 1"></button> <button pButton label="<<" (click)="moveAllToLeft()" [disabled]="rightSelection.length === 0"></button> </div> <!-- 右表格 --> <p-table [value]="rightData" [(selection)]="rightSelection" selectionMode="multiple" styleClass="w-64"> <ng-template pTemplate="header"> <tr> <th> <p-tableCheckbox></p-tableCheckbox> </th> <th>名称</th> <th>描述</th> </tr> </ng-template> <ng-template pTemplate="body" let-item> <tr [pSelectableRow]="item"> <td> <p-tableCheckbox [value]="item"></p-tableCheckbox> </td> <td>{{ item.name }}</td> <td>{{ item.description }}</td> </tr> </ng-template> </p-table> </div>
关键逻辑说明
- 用两个独立数组
leftData和rightData维护左右表格的数据源,避免数据混淆 - 通过
[(selection)]双向绑定选中项,直接获取用户勾选的行数据 - 单条迁移方法会判断选中项数量为1才执行,避免误操作;多条迁移则直接处理所有选中项
- 迁移时通过
filter方法从原数组移除选中项,用扩展运算符或push添加到目标数组 - 按钮添加
[disabled]属性,根据选中状态控制可用性,提升交互体验
内容的提问来源于stack exchange,提问作者intruder
相关产品推荐
相关产品推荐

