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

PrimeNG表格跨组拖拽问题:如何识别目标分组?

PrimeNG分组表格跨组拖拽:识别目标分组方案

我使用PrimeNG表格实现分组重排功能,目前同组内拖拽排序正常,但跨组拖拽时准确性不足,请问如何识别拖拽操作的目标分组?


我的代码

数据

this.data = [
      {
        id: 1,
        groupOrder: 1,
        group_by: { name: 'Manager', id: 1 },
        name: 'Manager 1',
        title: '1.1 Manager 1',
      },
      {
        id: 2,
        code: 1.2,
        groupOrder: 1,
        group_by: { name: 'Manager', id: 1 },
        name: 'Manager 2 ',
        title: '1.2 Manager 2',
      },
      {
        id: 3,
        groupOrder: 2,
        group_by: { name: 'Support', id: 2 },
        name: 'Support tel',
        title: '2.1 Support',
      },
      {
        id: 4,
        groupOrder: 2,
        group_by: { name: 'Support', id: 2 },
        name: 'Support app',
        title: '2.2 Support',
      },
    ];

TS代码

function array_move(arr, old_index, new_index) {
  if (new_index >= arr.length) {
    var k = new_index - arr.length + 1;
    while (k--) {
      arr.push(undefined);
    }
  }
  arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
  return arr; // for testing
}

rowTrackBy(_, item: any) {
    return item.id;
  }

  onRowReorder(data: any) {
    array_move(this.data, data.dragIndex, data.dropIndex);
  }

HTML代码

<div class="card">
  <p-table
    [value]="data"
    sortMode="single"
    [scrollable]="true"
    [rowTrackBy]="rowTrackBy"
    rowGroupMode="subheader"
    groupRowsBy="group_by.id"
    (onRowReorder)="onRowReorder($event)"
  >
    <ng-template pTemplate="header">
      <tr>
        <th>#</th>
        <th>item</th>
      </tr>
    </ng-template>

    <ng-template pTemplate="groupheader" let-item>
      <tr pRowGroupHeader>
        <td colspan="100" class="font-weight-bold">{{ item.group_by.name }}</td>
      </tr>
    </ng-template>

    <ng-template pTemplate="body" let-item let-rowIndex="rowIndex">
      <tr pDraggable="item" [pReorderableRow]="rowIndex">
        <td>
          <span class="pi pi-bars" pReorderableRowHandle></span>
        </td>
        <td>{{ item.code }} {{ item.name }}</td>
      </tr>
    </ng-template>
  </p-table>
</div>
<pre>{{data | json}}</pre>

解决方案

要准确识别跨组拖拽的目标分组,只需在onRowReorder事件中通过目标位置的行数据获取分组信息,同时更新被拖拽行的分组属性:

修改后的TS代码

function array_move(arr, old_index, new_index) {
  if (new_index >= arr.length) {
    var k = new_index - arr.length + 1;
    while (k--) {
      arr.push(undefined);
    }
  }
  arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
  return arr;
}

rowTrackBy(_, item: any) {
  return item.id;
}

onRowReorder(data: any) {
  // 获取被拖拽行和目标位置行
  const draggedItem = this.data[data.dragIndex];
  const targetItem = this.data[data.dropIndex];

  if (targetItem) {
    // 深拷贝目标分组信息,避免引用共享问题
    draggedItem.group_by = { ...targetItem.group_by };
    draggedItem.groupOrder = targetItem.groupOrder;
  }

  // 执行行重排
  array_move(this.data, data.dragIndex, data.dropIndex);
}

核心逻辑说明

  1. 定位目标分组:通过data.dropIndex找到目标位置对应的行,直接读取该行的group_by和groupOrder属性,这就是拖拽的目标分组
  2. 更新拖拽行分组:将被拖拽行的分组信息替换为目标分组的信息,注意使用对象展开运算符深拷贝,防止后续分组数据混乱
  3. 保持重排逻辑:原有的数组重排逻辑不变,更新分组信息后表格会自动重新渲染分组结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 07:32:34