Angular CdkDrag 元素在将项目转移到新列表后失去事件侦听器

Angular CdkDrag element loses event listener after transferring item to a new list

我正在使用 Angular 的拖放 CDK 在两个列表之间传输项目。我需要的一项特定功能是能够收听组件 API 提供的 cdkDrag 元素的 started Subject。但是,在我将项目转移到新列表后,我失去了事件侦听器。


这里的示例代码:https://stackblitz.com/edit/angular-m8lcqp

Fall Asleep 等元素移动到完成列表时,我将 started dragging 记录到控制台。但是,如果您尝试将该元素移回第一个列表,则不会触发该事件。我做错了什么?


为了订阅 started 事件,我使用 ViewChildren 获得 cdkDragQueryList。在 ngAfterViewInit() 中,我循环遍历这些拖动元素并订阅 started 事件:

ngAfterViewInit() {
  this.dragItems.forEach((drag) => {
    drag.started.subscribe((element) => {
      console.log('started dragging');
    })
  })
}

跟踪此事件的正确方法是什么?我是否需要检测页面上的更改,然后重新循环并重新订阅,因为 cdkDrag 元素现在位于不同的列表中?谢谢!

恐怕你是对的。将项目从一个列表移到另一个列表后,它会附加到另一个列表的新 CdkDrag 实例,因此您的订阅将停止接收排放。更糟糕的是,它似乎是内存泄漏的潜在来源,因为订阅从未被明确地拆除。

你最好的办法是直接在可拖动元素上添加一个监听器:

<div *ngFor="let item of done"
     (cdkDragStarted)="_dragStartedHandler($event)" 
     cdkDrag>{{item}}</div>
_dragStartedHandler(element: CdkDragStart) {
  console.log("started dragging");
}