2017-01-17 1 views
11

Wie kann ich in Angular2 ein Element innerhalb des HostListener-Dekorators ausrichten?Angular2, HostListener, wie kann ich ein Element anvisieren? Kann ich basierend auf der Klasse zielen?

@HostListener('dragstart', ['$event']) 
    onDragStart(ev:Event) { 
     console.log(ev); 
    } 

@HostListener('document: dragstart', ['$event']) 
    onDragStart(ev:Event) { 
     console.log(ev); 
    } 

@HostListener('myElement: dragstart', ['$event']) 
    onDragStart(ev:Event) { 
     console.log(ev); 
    } 

@HostListener('myElement.myClass: dragstart', ['$event']) 
    onDragStart(ev:Event) { 
     console.log(ev); 
    } 

Die beiden ersten Arbeit. Jede andere Sache, die ich versucht habe, wirft einen EXCEPTION: Unsupported event target undefined for event dragstart

Also, kann ich es zu einem gezielten Element implementieren? Wie?

+0

Können Sie rxjs verwenden Beobachter von den Eltern übergeben Kind des zugehörigen Event? –

Antwort

17

@HostListener() unterstützt nur window, document und body als globale Ereignisziele, andernfalls unterstützt es nur das Komponenten-Hostelement.

+0

Wenn ich dann einen Listener zu einem bestimmten Element einer Vorlage (einer Komponente) hinzufügen möchte, müsste ich dafür eine neue und getrennte Komponente erstellen? Sonst habe ich einen Listener für die gesamte Vorlage, oder? – Gerard

+3

Wenn das Element in Ihrer Komponente ist, können Sie einen der http://stackoverflow.com/questions/32693061/angular-2-typescript-get-hold-of-an-element-in-the-template/35209681#35209681 verwenden Um ein 'ElementRef' des Elements zu erhalten, können Sie' ElementRef.nativeElement.addEventListener (...) 'verwenden, oder Sie können http://stackoverflow.com/a/41610950/217408 verwenden. Wenn es außerhalb Ihrer Komponente ist, können Sie 'document.body.querySelector (...). AddEventListener (...)' –

+0

Die zweite Option funktioniert nicht für mich wegen http://stackoverflow.com/questions/41695838/angular2-templates-sind-nur-teilweise-ausgeführt-wenn-ngaftercontentinit-oder? Noredirect = 1 # comment70589895_41695838 und ich versuche, jetzt Ihren ersten Link zu verstehen, danke! – Gerard

6

Da die akzeptierte Antwort nicht wirklich hilft, das Problem zu lösen, hier ist eine Lösung.

Eine bessere Möglichkeit, dies zu erreichen, besteht darin, eine Direktive zu erstellen. Auf diese Weise können Sie die Direktive zu einem beliebigen Element hinzufügen, und die Listener werden nur für dieses bestimmte Element ausgelöst.

Zum Beispiel:

@Directive({ 
    selector: "[focus-out-directive]" 
}) 
export class FocusOutDirective { 
    @Output() onFocusOut: EventEmitter<boolean> = new EventEmitter<false>(); 

    @HostListener("focusout", ["$event"]) 
    public onListenerTriggered(event: any): void { 
     this.onFocusOut.emit(true); 
    } 
} 

dann auf Ihre HTML-Elemente, die Sie diesen Listener anwenden möchten, die Richtlinie Wähler auf, fügen Sie einfach in diesem Fall focus-out-directive, und dann liefern die Funktion, die Sie auf Ihrer Komponente auslösen wollen .

Beispiel:

<input type='text' focus-out-directive (onFocusOut)='myFunction($event)'/>

0

auf einem Element hören:

import { Renderer2 } from '@angular/core'; 
... 
constructor(private renderer: Renderer2) {} 

// Get this.myElement with document.getElement... or ElementRef 

ngOnInit() { 
    // scroll or any other event 
    this.renderer.listen(this.myElement, 'scroll', (event) => { 
    // Do something with 'event' 
    console.log(this.myElement.scrollTop); 
}); 

}

Verwandte Themen