2017-05-24 6 views
3

mousemoveリスナーmousedownイベントが実行されている場合にのみ、役に立たないリスナーを設定しないようにします。そのような何か:他のマウスイベントで@Hostlistnerを実行できますか?

私component.ts

private startMouseMove(start: boolean){ 
    if(start){ 
     @HostListener('mousemove', ['$event']) 
     onMouseMove(event: MouseEvent){ 
      console.log("start mousemove");  
      this.mousemove.emit(event); 
     } 
    } 
} 

@HostListener('mouseup', ['$event']) 
onMouseup(event: MouseEvent){ 
    console.log(event.type); 
    this.startMouseMove(false); 
} 

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

インサイドもちろん動作しません。 Angularで可能かどうかを知りたい場合は可能ですか?これを行う方法は?

答えて

1

一つの可能​​な解決策は、反応性のアプローチを使用してすることができます

import { Observable } from 'rxjs/Observable'; 
import { Subscription } from 'rxjs/Subscription'; 
import 'rxjs/add/observable/fromEvent'; 
import 'rxjs/add/operator/mergeMap'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/takeUntil'; 

@Directive({ 
    selector: '[my-drag]' 
}) 
export class DragDirective { 
    subscription: Subscription; 

    constructor(private elRef: ElementRef, private zone: NgZone) {} 

    ngOnInit() { 
     this.zone.runOutsideAngular(() => this.initDragEvent()); 
    } 

    initDragEvent() { 
     const el = this.elRef.nativeElement; 
     const mousedown = Observable.fromEvent(el, 'mousedown'); 
     const mouseup = Observable.fromEvent(el, 'mouseup'); 
     const mousemove = Observable.fromEvent(document, 'mousemove'); 
     const mousedrag = mousedown.flatMap((md: any) => { 
      const startX = md.offsetX; 
      const startY = md.offsetY; 

      return mousemove.map((e: any) => { 
       e.preventDefault(); 
       return { 
        left: e.clientX - startX, 
        top: e.clientY - startY 
       }; 
      }).takeUntil(mouseup); 
     }); 

     this.subscription = mousedrag.subscribe((pos) => { 
      console.log('mousemove is fired'); 
      el.style.top = pos.top + 'px'; 
      el.style.left = pos.left + 'px'; 
     }); 
    } 

    ngOnDestroy() { 
     if(this.subscription) { 
      this.subscription.unsubscribe(); 
     } 
    } 
} 

私は検出が発生した冗長な変更をしたくないので、私は角度のゾーンのうちinitDragEventを実行しています。

別の解決策は、レンダラ

export class DragDirective { 
    listener: Function; 

    @HostListener('mouseup', ['$event']) 
    onMouseup(event: MouseEvent) { 
     console.log(event.type); 
     this.startMouseMove(false); 
    } 

    @HostListener('mousedown', ['$event']) 
    onMousedown(event: MouseEvent) { 
     console.log(event.type); 
     this.startMouseMove(true); 
     return false; 
    } 

    constructor(private renderer: Renderer2) {} 

    private startMouseMove(start: boolean) { 
     this.ngOnDestroy(); 
     if (start) { 
      this.listener = this.renderer.listen(document, 'mousemove',() => { 
       console.log("start mousemove", this.listener); 
      }) 
     } 
    } 

    ngOnDestroy() { 
     if(this.listener) { 
      this.listener(); 
     } 
    } 
} 

Plunker Example

+0

を使用している私はRenderer2の方法は、後のV4への角度に更新しようとしました。それは完璧に動作します! –

関連する問題