There are three types of connection.
DragSource
is for allowing components to be dragged. Create one with
SkyhookDndService#dragSource
using a
DragSourceSpec
and attach it to the DOM
with [dragSource]="..."
.
DropTarget
is for allowing components to be dragged. Create one with
SkyhookDndService#dropTarget
using a
DropTargetSpec
and attach it to the DOM
with [dropTarget]="..."
.
DragLayer is an advanced feature that allows you to implement your own custom drag previews. Create one with SkyhookDndService#dragLayer, but you don't attach them to the DOM, you simply listen for changes.
All three of them have the same lifecycle, and all three of them offer a
.listen()
function, which allows you to listen to changes. See
ConnectionBase for what they have in
common.
SkyhookDndService
to create connectionsFirst, inject SkyhookDndService, into your component.
constructor(private dnd: SkyhookDndService) { ... }
Then, use one of the methods
SkyhookDndService#dragSource,
SkyhookDndService#dropTarget
to create one and store it as an instance variable, and make sure to tear down
the connection in ngOnDestroy
.
source = this.dnd.dragSource("CAT", {
beginDrag: (monitor) => ({ id: this.cat.id })
// ...
});
// or
target = this.dnd.dropTarget(["CAT", "ZEBRA"], {
// ...
});
constructor(private dnd: SkyhookDndService) { ... }
ngOnDestroy() {
this.source.unsubscribe();
// or
this.target.unsubscribe();
}
Then, you will want to add some behaviour beyond the default by looking into the Spec input for your connection type.
All three types of connection need to be destroyed when your component is destroyed. If you don't, you will have strange problems.
The easy way is to call
.unsubscribe()
on the
connection object in ngOnDestroy
.
ngOnDestroy() {
this.source.unsubscribe();
this.target.unsubscribe();
this.layer.unsubscribe();
// neat. we're done.
}
In situations where your component has a lot of subscription logic to maintain, there are more powerful ways of unsubscribing to many things at once.
You can create an RxJS Subscription
object in your component, and call
Subscription.add(conn)
with your connection. There is a convenience parameter
on each of the SkyhookDndService
methods which will do this for you.
import { Subscription } from 'rxjs';
// ...
subs = new Subscription();
source = this.dnd.dragSource({
// ...
}, this.subs);
target = this.dnd.dragSource({
// ...
}, this.subs);
// ...
ngOnInit() {
// subscribe to lots of things here
this.subs.add(myService.subscribe(...));
this.subs.add(myService.subscribe(...));
this.subs.add(myService.subscribe(...));
this.subs.add(myService.subscribe(...));
}
ngOnDestroy() {
// This will unsubscribe everything, including source and target
this.subs.unsubscribe();
}
(It is not recommended to have a large number of drag sources and drop targets
attached to a single component, especially not in a variably-sized array,
simply because that is poor component structure. Instead, consider creating a
component that handles a single piece of dragging logic, and use an *ngFor
over
the whole component.)