Cómo implementar un div arrastrable en Angular 2 usando Rx

He estado tratando de hacer que un div arrastrable funcione con Angular 2. Estoy usandoeste ejemplo del repositorio angular2-examples como punto de partida, solo ajustando realmente el código para tener en cuenta la eliminación deltoRx() método. El código funciona, pero no tiene en cuentamouseout eventos. Esto significa que si hago clic en un div que se puede arrastrar y muevo el mousedespacio, el div se moverá con el mouse. Pero si muevo el mouse demasiado rápido, unmouseout se envía un evento en lugar de unmousemove evento, y se detiene el arrastre.

¿Cómo puedo mantener el arrastre después de mover el mouse tanto quemouseout evento es despedido? He intentado fusionar elmouseout secuencia de eventos con elmousemove uno, para quemouseout los eventos son tratados comomousemove unos, pero eso no funciona.

Estoy usando Angular 2.0.0-beta.12.

import {Component, Directive, HostListener, EventEmitter, ElementRef, OnInit} from 'angular2/core';
import {map, merge} from 'rxjs/Rx';

@Directive({
    selector: '[draggable]'
})
export class Draggable implements OnInit {

    mouseup = new EventEmitter();
    mousedown = new EventEmitter();
    mousemove = new EventEmitter();
    mouseout = new EventEmitter();

    @HostListener('mouseup', ['$event'])
    onMouseup(event) {
        this.mouseup.emit(event);
    }

    @HostListener('mousedown', ['$event'])
    onMousedown(event) {
        this.mousedown.emit(event);
        return false; // Call preventDefault() on the event
    }

    @HostListener('mousemove', ['$event'])
    onMousemove(event) {
        this.mousemove.emit(event);
    }

    @HostListener('mouseout', ['$event'])
    onMouseout(event) {
        this.mouseout.emit(event);
        return false; // Call preventDefault() on the event
    }

    constructor(public element: ElementRef) {
        this.element.nativeElement.style.position = 'relative';
        this.element.nativeElement.style.cursor = 'pointer';

        map;
        merge;
        this.mousedrag = this.mousedown.map(event => {
            return {
                top: event.clientY - this.element.nativeElement.getBoundingClientRect().top
                left: event.clientX - this.element.nativeElement.getBoundingClientRect().left,
            };
        })
        .flatMap(
            imageOffset => this.mousemove.merge(this.mouseout).map(pos => ({
                top: pos.clientY - imageOffset.top,
                left: pos.clientX - imageOffset.left
            }))
            .takeUntil(this.mouseup)
        );
    }

    ngOnInit() {
        this.mousedrag.subscribe({
            next: pos => {
                this.element.nativeElement.style.top = pos.top + 'px';
                this.element.nativeElement.style.left = pos.left + 'px';
            }
        });
    }
}

@Component({
    selector: 'my-app',
    template: `
        <div draggable>
            <h1>Hello, World!</h1>
        </div>
        `,
    directives: [Draggable,],
})
export class AppComponent {
}

Respuestas a la pregunta(4)

Su respuesta a la pregunta