How to append dynamic DOM elements from a directive in Angular 2?

user11081980 picture user11081980 · Jul 13, 2017 · Viewed 33.8k times · Source

I have an Angular 1.x directive that appends an element. In short:

app.directive('mydirective', function() {
  template: '<ng-transclude></ng-transclude>',
  link: function(el) {
    var child = angular.element("<div/>");
    el.append(child);
  }

I can migrate this directive to Angular 2 like this:

@Directive({
  selector: '[mydirective']
})
export class MyDirective implements OnInit {
  constructor(private elementRef: ElementRef) { }

  ngOnit() {
    var child = angular.element("<div/>");
    this.elementRef.nativeElement.append(child);
  }
}

What's troubling me is this remark in the nativeElement official documentation:

Use this API as the last resource when direct access to DOM is needed.

My question is - how could I properly migrate this directive to Angular 2? My only requirement is to build an element dynamically and append it to the element with the directive.

Answer

Max Koretskyi picture Max Koretskyi · Jul 13, 2017

Use Renderer provided by the Angular to manipulate the DOM:

import { DOCUMENT } from '@angular/common';

export class MyDirective implements OnInit {
  constructor(private elementRef: ElementRef, private renderer: Renderer2, @Inject(DOCUMENT) private document) { }

  ngOnInit() {
    const child = document.createElement('div');
    this.renderer.appendChild(this.elementRef.nativeElement, child);
  }
}

This doesn't depend on the native DOM API like appendChild(), so in a way it's a platform-independent approach.