Reputation: 162
I have the following, hopefully fairly standard, drag and drop code using Rxjs in Angular 2.
The blockElement
happens to be an SVG rectangle but I don't think that makes any difference to the question.
I need to set the coordinates of the blockElement
when it's finally dropped, i.e. when the mouseup
event fires at the end of the drag. This is so that the user can drop it roughly in the right place and the code lines up its position correctly.
Can I achieve that by reacting to the takeUntil
by running a function? Or is there some other Rxjs operator I can use to react to mouseup
by running a function when it happens at the end of the drag?
(I've edited the code for clarity, but the actual code does work, so if there's any errors in what follows it shouldn't be relevant to the question and hopefully you get the idea)
const taskMouseDown$ = Observable.fromEvent(this.blockElement.nativeElement, 'mousedown');
const documentMouseUp$ = Observable.fromEvent(document, 'mouseup');
const documentMouseMove$ = Observable.fromEvent(document, 'mousemove');
const taskMouseDrag$ = taskMouseDown$.flatMap((mouseEvent: MouseEvent) => {
return documentMouseMove$.map((mouseMoveEvent: MouseEvent) => {
return ({mouseStart: mouseEvent, mouseCurrent: moveMouseEvent});
}).takeUntil(documentMouseUp$);
});
taskMouseDrag$.subscribe(
// Make the block element follow the mouse
});
Upvotes: 0
Views: 1727
Reputation: 214037
1) You can use do
operator like
.takeUntil(documentMouseUp$)
.do(
() => {}, // next
() => {}, // error
() => { // complete
alert('mouseup')
}
);
or
declare module "rxjs/Observable" {
interface Observable<T> {
finish : typeof finish;
}
}
function finish<T>(this : Observable<any>, fn: () => void): Observable<T> {
return this.do(() => {}, () => {}, fn);
}
Observable.prototype.finish = finish;
...
.takeUntil(documentMouseUp$)
.finish(() => this.onMouseUp());
2) Or you can just subscribe to documentMouseUp$
documentMouseUp$.subscribe(() => console.log('mouseup);
Upvotes: 1
Reputation: 14375
takeUntil
terminates the stream when the condition is met and you can pass a handler for this:
takeMouseDrag$.subscribe(
nextHandler, // your move handler
completeHandler, // this gets triggered when the mouseup triggers the take until
errorHandler // in case you want to handle errors
}
or in you case:
takeMouseDrag$.subscribe(
onDrag,
onDragEnd
)
Upvotes: 0