page - hostlistener hostbinding angular
Angular2, HostListener, ¿cómo puedo apuntar a un elemento? ¿Puedo apuntar en base a la clase? (7)
Como lo señaló Googs, la respuesta aceptada responde a la pregunta pero no ayuda a encontrar una solución.
Aproveché la respuesta de alex porque necesitaba una forma de usar la funcionalidad que ya tenía en mi @HostListener
para recuperar una lista de notificaciones para diferentes tamaños de pantalla.
Por ejemplo, en mi aplicación, la página de notificaciones tiene su propia ruta en el móvil, pero existía en la barra lateral de la tableta y en los tamaños de pantalla anteriores, por lo que no podía usar el @HostListener
allí, ya que solo se @HostListener
cuando llegara al final de la pantalla. Toda la página y no la barra lateral.
En cambio, busqué el <div>
que estaba interesado y adjunté lo que necesitaba. Así que el siguiente código:
attachListenerToContainer() {
let elementToListenTo = this.ele ? this.ele : ''window'';
this.renderer.listen(elementToListenTo, ''scroll'', (event) => {
if(!this.reachedBottom) {
if((getHeight(this.ele) + getScrollTop(this.ele)) >= getOffset(this.ele)) {
this.reachedBottom = true;
this.getNextNotificationsPage();
}
}
});
function getScrollTop(ele) {
return ele ? ele.scrollTop : window.scrollY;
}
function getHeight(ele) {
return ele ? ele.clientHeight : window.innerHeight;
}
function getOffset(ele) {
return ele ? ele.scrollHeight : document.body.offsetHeight;
}
}
El this.ele
es el div contenedor que me interesa, y busco en el gancho de ciclo de vida ngAfterViewInit()
para tabletas y superiores. Si no puedo encontrar ese elemento, entonces uso la ventana en su lugar, emulando efectivamente el @HostListener
Además, así es como estaba buscando, en mi caso, el elemento contenedor que quería:
this.ele = document.getElementsByClassName(''notifications'')[0];
En Angular2, ¿cómo puedo apuntar a un elemento dentro del decorador HostListener?
@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);
}
Los dos primeros trabajos. Cualquier otra cosa que haya intentado genera una EXCEPTION: Unsupported event target undefined for event dragstart
Entonces, ¿puedo implementarlo en un elemento específico? ¿Cómo?
Creo que la mejor manera para el oyente global es @hostliterner, pero si quieres apuntar a algún elemento, puedes hacerlo de esta manera
<div (event)="onEvent($e)"></div>
en tu componente angular
onEvent($e) { //do something ... }
Escucha en un elemento:
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);
});
}
También puede apuntar a cualquier elemento sin @hostlistener y puede agregar los eventos necesarios de la siguiente manera
import { AfterViewInit, Component, ElementRef} from ''@angular/core'';
constructor(private elementRef:ElementRef) {}
ngAfterViewInit() {
this.elementRef.nativeElement.querySelector(''my-element'')
.addEventListener(''click'', this.onClick.bind(this));
}
onClick(event) {
console.log(event);
}
Ya que la respuesta aceptada no ayuda realmente a resolver el problema, aquí hay una solución.
Una mejor manera de lograr esto es mediante la creación de una directiva, de esta manera puede agregar la directiva a cualquier elemento que desee, y los oyentes solo activarán este elemento en particular.
Por ejemplo:
@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);
}
}
Luego, en los elementos HTML a los que desea aplicar esta escucha, simplemente agregue el selector de directivas, en este caso, la directiva de focus-out-directive
, y luego suministre la función que desea activar en su componente.
Ejemplo:
<input type=''text'' focus-out-directive (onFocusOut)=''myFunction($event)''/>
@HostListener()
solo admite window
, document
y body
como objetivos de eventos globales, de lo contrario, solo es compatible con los componentes del elemento host.
import { Directive, ElementRef, OnInit, Output, EventEmitter} from ''@angular/core'';
@Directive({
selector: ''[checkClick]''
})
export class checkClickDirective implements OnInit {
@Output() public checkClick = new EventEmitter();
constructor(private _el: ElementRef) { }
@HostListener(''click'', [''$event.target'']) public onClick(targetElement) {
const checkClick = this._el.nativeElement.contains(targetElement);
(checkClick)?this.checkClick.emit(true):this.checkClick.emit(false);
}
}