如何使用Rx在Angular 2中实现可拖动的div

前端之家收集整理的这篇文章主要介绍了如何使用Rx在Angular 2中实现可拖动的div前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直试图让一个可拖动的div工作使用Angular 2.我使用 this example from the angular2-examples repo作为起点,只是真正调整代码来解释toRx()方法删除.该代码有效,但它不考虑mouSEOut事件.这意味着如果我单击一个Draggable div,然后慢慢移动鼠标,div将随鼠标移动.但是如果我移动鼠标太快,则会发送mouSEOut事件而不是mousemove事件,并且拖动停止.

鼠标移动到目前为止,如何触发mouSEOut事件,如何保持拖动?我已尝试将mouSEOut事件流与mousemove one合并,因此mouSEOut事件的处理就像mousemove事件一样,但这不起作用.

我正在使用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 {
}
我在 RxJs How do deal with document events中找到了答案.问题的关键在于当鼠标悬停在该元素上时,鼠标事件仅发送到元素.所以我们确实希望mousedown事件仅限于特定元素,但我们必须跟踪全局mousemove和mouseup事件.这是新代码.注意在onMouseup和onMousemove上使用@HostListener装饰器将目标指定为document:mouseup和document:mousemove.这是全局事件通过管道传输到Rx流的方式.

official angular2 documentation for HostListener没有提到这个目标:eventName语法,但this old dart documentation for 2.0.0-alpha.24确实提到了它.它似乎仍然适用于2.0.0-beta.12.

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

    mouseup = new EventEmitter<MouseEvent>();
    mousedown = new EventEmitter<MouseEvent>();
    mousemove = new EventEmitter<MouseEvent>();

    mousedrag: Observable<{top,left}>;

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

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

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

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

        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.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';
            }
        });
    }
}

猜你在找的Angularjs相关文章