javascript - ¿Por qué nativeElement es indefinido?
En mi componente padre, tengo un botón y una directiva de menú de configuración. Lo que estoy intentando hacer es pasar el elementref #navBtn como una entrada en settings-menu.
<div #navBtn (click)="toggleNav()" class="header__button header__button--left" id="header_button--left">
<img class="align-absolute" src="assets/imgs/icon_sandwich.svg">
</div>
<settings-menu [btn]="navBtn" [navOpened]="navOpened" (navClosed)="navOpened.next(false)"></settings-menu>
...
@ViewChild('navBtn') navBtn: ElementRef;
Necesito este elementref para poder verificar si un objetivo de evento incluye/excluye este elemento en un HostListener en offclick.
private _btn: ElementRef;
@Input('navOpened') navOpened: BehaviorSubject<boolean>;
@Input('btn')
set btn(val: ElementRef) {
this._btn = val;
}
get btn() {
return this._btn;
}
@HostListener('document:click', ['$event']) offClick(e: Event) {
e.stopPropagation();
console.log('el', this.el.nativeElement, 'btn', this.btn.nativeElement, 'target', e.target);
if (!this.el.nativeElement.contains(e.target) || this.btn.nativeElement.contains(e.target)) this.closeNav();
}
Pero this.btn devuelve el HTML del botón y no un elementRef, parece, porque nativeElement en this.btn siempre es indefinido, incluso en el hook del ciclo de vida ngAfterViewInit.
Respuesta #1
Como se menciona en la documentación de Angular sobre variables de referencia de plantilla:
<input #phone placeholder="phone number">
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
En la mayoría de los casos, Angular establece el valor de la variable de referencia al elemento en el que fue declarada. En el ejemplo anterior, phone se refiere a la caja del número de teléfono. El manejador de clic del botón phone pasa el valor del input al método callPhone del componente.
En tu código, si pasas navBtn como un valor de entrada a settings-menu:
<settings-menu [btn]="navBtn" ...>
btn se establecerá en el elemento DOM al que se hace referencia mediante #navBtn. Podrías definir la variable btn como un HTMLElement en el componente settings-menu:
@Input("btn") btn: HTMLElement;
Por otro lado, si recuperas el elemento con @ViewChild("navBtn") en su propio componente, entonces obtienes un ElementRef, con una propiedad nativeElement que apunta al elemento del DOM.
