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!
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");
}