如何获取已删除另一个列表项的列表项

How to get a list item on which another list item was dropped

假设我有两个列表:一些产品的列表和产品类别的列表。我希望能够通过将产品放在相应的类别列表项上来将其移至类别。这是一个简单的例子:

<mat-list id="product-list" cdkDropList cdkDropListConnectedTo="category-list">
  <mat-list-item *ngFor="let product of products" cdkDrag>
      <span>product.name</span>
  </mat-list-item>
</mat-list>

<mat-list id="category-list" cdkDropList (cdkDropListDropped)="onDrop($event)">
  <mat-list-item *ngFor="let category of categories">
      <span>category.name</span>
  </mat-list-item>
</mat-list>

现在调用了 onDrop 处理程序,但我不知道如何确定在其上放置了产品列表项的类别列表项。由于类别列表项不可拖动 currentIndex 在事件中始终为零。

Angular/AngularMaterial 的版本是 12.1.3。

最后我设法用 elementFromPoint 函数解决了这个问题。这是更新后的示例:

<mat-list id="product-list" cdkDropList>
  <mat-list-item *ngFor="let product of products" cdkDrag
                 (cdkDragEnded)="onDragEnded($event, product)">
    <span>product.name</span>
  </mat-list-item>
</mat-list>

<mat-list id="category-list">
  <mat-list-item *ngFor="let category of categories" class="drop-receiver"
                 (_drop)="onDrop($event, category)">
    <span>category.name</span>
  </mat-list-item>
</mat-list>

您可以看到列表不再连接。类别列表看起来像一个普通的,除了它的项目有 class drop-receiver 和自定义 _drop 事件的侦听器。

在产品列表中我监听了 cdkDragEnded 事件。这是事件处理程序的代码:

onDragEnded(event: CdkDragEnd, product: Product) {
  const dropPointElement = document.elementFromPoint(event.dropPoint.x, event.dropPoint.y);
  if (dropPointElement) {
    const dropReceiver = dropPointElement.closest('.drop-receiver');
    if (dropReceiver) {
      const dropEvent = new CustomEvent('_drop', {detail: product});
      dropReceiver.dispatchEvent(dropEvent);
    }
  }
}

在上面的示例中,我使用放置点坐标查找 DOM 元素。然后,如果找到元素,我会寻找最接近 DOM 且 class drop-receiver 的元素。最后,我将名称为 _drop 的自定义事件发送到放置接收器元素。现在在该事件的处理程序中,可以实现将类别分配给所选产品的一些逻辑。