Reputation: 3749
I'm trying to bind an event to a "dynamic" element created by a directive in Angular 2, my code looks like this:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
@Input() defaultColor: string;
@Input('myHighlight') highlightColor: string;
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || this.defaultColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color = "red") {
this.el.nativeElement.style.backgroundColor = color;
}
ngAfterContentInit() {
var hbElement = document.createElement('button');
hbElement.innerText = 'Highlight';
hbElement.addEventListener('click', this.highlight);
this.el.nativeElement.appendChild(hbElement);
}
}
But when I click on the hbElement
(button) I get the error: Cannot read property 'nativeElement' of undefined
I imagine that this is because this.el is null so the click is called outside this directive context.
How can I add the event on click in the hbElement so it can access the attributes of the Directive instance?
Upvotes: 2
Views: 241
Reputation: 28397
You have to bind highlight
to the Directive.
In order to achieve that, you can use .bind(this)
ngAfterContentInit() {
var hbElement = document.createElement('button');
hbElement.innerText = 'Highlight';
hbElement.addEventListener('click', this.highlight.bind(this)); // Here
this.el.nativeElement.appendChild(hbElement);
}
Or you can use an arrow function
private highlight = (color = "red") => {
this.el.nativeElement.style.backgroundColor = color;
}
Upvotes: 2