0

I am using Angular's Drag Drop CDK to transfer items between two lists. One specific functionality I need is to be able to listen to the cdkDrag element's started Subject provided by the component API. However, after I transfer the item to a new list, I lose the event listener.


Example code here: https://stackblitz.com/edit/angular-m8lcqp

When moving an element such as Fall Asleep to the Done list, I log started dragging to the console. But if you try to move that element back to the first list, the event is not fired. What am I doing incorrectly?


To subscribe to the started event, I use ViewChildren to get a QueryList of cdkDrag. Within an ngAfterViewInit(), I loop through these drag elements and subscribe to the started event:

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

What is the correct way to track this event? Do I need to detect changes on the page and then re-loop through and resubscribe since the cdkDrag element is now in a different list? Thank you!

Jordan Lewallen
  • 1,681
  • 19
  • 54

1 Answers1

0

I'm afraid you're right. Once you moved an item from one list to the other, it's attached to a new CdkDrag instance of the other list so your subscription stops receiving emissions. Worse than that, it seems to be a potential source of memory leaking, as the subscription is never torn down explicitly.

Your best shot is adding a listener directly on the draggable element:

<div *ngFor="let item of done"
     (cdkDragStarted)="_dragStartedHandler($event)" 
     cdkDrag>{{item}}</div>
_dragStartedHandler(element: CdkDragStart) {
  console.log("started dragging");
}
julianobrasil
  • 8,954
  • 2
  • 33
  • 55
  • You're absolutely right, I wonder if this is something I should submit as a bug to the Angular team? Anyways, I completely forgot about the HTML output events, so this actually works much better than what I was trying to do...thanks! – Jordan Lewallen Apr 13 '20 at 05:31