JohnnyAce
JohnnyAce

Reputation: 3749

How to manage the click event from appended element in directive?

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

Answers (1)

QoP
QoP

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;
}

plnkr

Upvotes: 2

Related Questions