Reputation: 92447
I use Angular2 and write some @Directive with drag and drop (in some bounded area) and want to emit event when dragging is end - so when dragging is end I invoke method endDragging. 1. how body of this method should look like?, 2. how usage of this directive should look like (especially how to set eventHandler to directive).
@Directive({
selector: '[draggable]'
})
export class Draggable {
@Input('draggable') boundary: any;
...
endDraging() {
// ??? how emit event from here?
}
}
In html template (???=how set handler for draggable-endDragging event):
<div [draggable]="{x_min:10, x_max:100, y_min:20, y_max:200}" ...???... >
...some content...
</div>
Upvotes: 0
Views: 122
Reputation: 92447
I found some working solution but unfortunatly is a little bit dirty workaround:
Let say we have component which use draggable div in his template:
@Component({
selector: 'my-component',
templateUrl: './my-component.html',
directives: [ Draggable ],
})
export class MyComponent {
myVariable = 0;
boundary() {
return {
x_min:10,
x_max:100,
y_min:20,
y_max:200,
self: this,
onDragEnd: this.onDragEnd,
};
}
onDragEnd(x,y,boundary) {
// handle drag end event, to get acces to 'this' (instance of MyComponent class use boundary.self)
boundary.self.myVariable = 1;
}
}
In template .html we have:
<div [draggable]="boundary()">...</div>
And out directive will look like that:
@Directive({
selector: '[draggable]'
})
export class Draggable {
@Input('draggable') boundary: any;
...
endDraging() {
this.boundary.onDragEnd(this.x,this.y, this.boundary);
}
}
The dirty thing is that MyComponent.onDragEnd method don't have access to 'this'(!!!) so I must put "this" in 'self' in object retuned by boundary() method. I don't know what is the reason - may be angular causes that, or may be typescript causes that problem... i don't know.
UPDATE:
I think that if we change line onDragEnd: this.onDragEnd,
in MyComponent
to
onDragEnd: (x,y,boundary) => this.onDragEnd(x,y,boundary),
then we will have normal access to this
inside onDragEnd
and solution actually will be not "dirty".
Upvotes: 1
Reputation: 72
You can define service with global event and use it in directive
import { Injectable } from '@angular/core';
import { ReplaySubject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class GlobalEventService {
private eventSubject = new ReplaySubject<string>(1);
constructor() { }
public getEventObservable() {
return this.eventSubject.asObservable();
}
public emitEvent(message) {
this.eventSubject.next(message);
}
}
Code is out of head and may contain bugs. From outside someone in service do
globalEventService.getEventObservable().subscribe(message => { … })
while directive use this servis sending event like this
globalEventService.emitEvent('some messsage')
Upvotes: 1