After creating a directive to enable a drop-down menu on my header, I encountered an issue. Rather than utilizing the hostListeners property on the @Directive decorator, I opted to implement it using vanilla JavaScript. Initially, the code functioned correctly. However, after refactoring the functions as standalone functions instead of anonymous functions, the functionality broke.
import { Directive, OnInit, ElementRef, OnDestroy } from '@angular/core';
@Directive({
selector: '[headerDropdown]'
})
export class HeaderDropdownDirective implements OnInit, OnDestroy {
private isActive: boolean;
private isAbove: boolean;
private dropDownElement: Element;
private downArrowElement: Element;
constructor(private elementRef: ElementRef) { }
ngOnInit() {
this.dropDownElement = document.querySelector('.header__dropdown');
this.downArrowElement = this.elementRef.nativeElement;
this.downArrowElement.addEventListener('mouseenter', this.downArrowOnMouseEnter);
this.downArrowElement.addEventListener('mouseleave', this.downArrowOnMouseLeave);
this.downArrowElement.addEventListener('click', this.downArrowOnClick);
document.addEventListener('click', this.documentOnClick);
}
ngOnDestroy() {
// TODO: removeEventListener
}
private activate() {
this.isActive = true;
this.downArrowElement.classList.add('header__item--active');
this.dropDownElement.classList.add('header__dropdown--active');
}
private deActivate() {
this.isActive = false;
this.downArrowElement.classList.remove('header__item--active');
this.dropDownElement.classList.remove('header__dropdown--active');
}
private downArrowOnMouseEnter() {
this.isAbove = true;
}
private downArrowOnMouseLeave() {
this.isAbove = false;
}
private downArrowOnClick() {
if (!this.isActive) {
this.activate();
} else {
this.deActivate();
}
}
private documentOnClick() {
if (!this.isAbove) {
this.deActivate();
}
}
}
When interacting with the downArrow button, I encounter the following error:
EXCEPTION: this.activate is not a function
ErrorHandler.handleError @ VM12616:55
next @ VM12615:374
schedulerFn @ VM12630:100
SafeSubscriber.__tryOrUnsub @ VM12634:236
SafeSubscriber.next @ VM12634:185
...
<p>However, modifying the code like this resolves the issue:</p>
<pre><code>import { Directive, OnInit, ElementRef, OnDestroy } from '@angular/core';
@Directive({
selector: '[headerDropdown]'
})
export class HeaderDropdownDirective implements OnInit, OnDestroy {
private isActive: boolean;
private isAbove: boolean;
private dropDownElement: Element;
private downArrowElement: Element;
constructor(private elementRef: ElementRef) { }
ngOnInit() {
this.dropDownElement = document.querySelector('.header__dropdown');
this.downArrowElement = this.elementRef.nativeElement;
this.downArrowElement.addEventListener('mouseenter', () => { this.isAbove = true; });
this.downArrowElement.addEventListener('mouseleave', () => { this.isAbove = false; });
this.downArrowElement.addEventListener('click', () => {
if (!this.isActive) {
this.activate();
} else {
this.deActivate();
}
});
document.addEventListener('click', () => {
if (!this.isAbove) {
this.deActivate();
}
});
}
...
}
I have attempted changing the access level of the functions to public, but the problem persists with the same error message.