David Aguirre
David Aguirre

Reputation: 1410

Adding event listener to dynamic element in Angular 4?

I have some description text from an API that I am inserting as HTML into the DOM.

<div class="activity-description" [innerHTML]="description"></div>

The description is set within ngOninit();

if (this.eventDetail.description.length > 255) {
   this.description = this.eventDetail.description.substring(0, 255) + '<span class="more-description"> ...Learn More</span>';
}

I am trying to add an event listener to the "more-description" class within the ngAfterViewInit()

var el = this.elementRef.nativeElement.querySelector('.more-description');
    if (el)
        el.addEventListener('click', this.displayFullDescription());

The element is null and does not allow the event listener to be attached. How do I add this event listener to html elements that are dynamically added?

Upvotes: 3

Views: 16726

Answers (1)

yurzui
yurzui

Reputation: 214047

You can manually render view by calling cdRef.detectChanges:

constuctor(private cdRef: ChangeDetectorRef) {}

ngOnInit() {
  if (this.eventDetail.description.length > 255) {
    this.description = this.eventDetail.description.substring(0, 255) +
                      '<span class="more-description"> ...Learn More</span>';
  }
}

ngAfterViewInit() {
  this.cdRef.detectChanges();
  var el = this.elementRef.nativeElement.querySelector('.more-description');
}

Update

Perhaps you made some mistake in this code:

el.addEventListener('click', this.displayFullDescription());

I don't know what displayFullDescription function does.

Here is working example:

@Component({
  selector: 'event',
  template: `
    <div class="activity-description" [innerHTML]="description"></div>
  `,
})
export class Event {
  @Input() eventDetail: any;

  description: string;

  constructor(private elementRef: ElementRef) { }

  ngOnInit() {
    if (this.eventDetail.description.length > 255) {
       this.description = this.eventDetail.description.substring(0, 255) + '<span class="more-description"> ...Learn More</span>';
    }
  }

  displayFullDescription() {
    this.description = this.eventDetail.description;
  }

  ngAfterViewInit() {
    var el = this.elementRef.nativeElement.querySelector('.more-description');
    if(el) {
      el.addEventListener('click', this.displayFullDescription.bind(this));
    }
  }
}

Plunker Example

Note: It would be better if you store handler in class property so that you can unsubscribe later.

Upvotes: 11

Related Questions