DEV Community

Muhammad Awais
Muhammad Awais

Posted on

DOM manipulation in Angular using @ViewChild, ElementRef

@ViewChild

Before we explore the DOM abstractions, let’s understand how we access these abstractions inside a component/directive class. Angular provides a mechanism called DOM queries. It comes in the form of @ViewChild and @ViewChildren decorators. They behave the same, only the former returns one reference, while the latter returns multiple references as a QueryList object. In the examples in this article, I’ll be using mostly the ViewChild decorator and will not be using the @ symbol before it.

The basic syntax of the ViewChild decorator is:

@ViewChild('child1', {static: false}) firstChild: ElementRef;
Enter fullscreen mode Exit fullscreen mode

ElementRef

This is the most basic abstraction. If you observe its class structure, you’ll see that it only holds the native element it’s associated with. It’s useful for accessing the native DOM element as we can see here:

console.log(this.tref.nativeElement.innerHTML);

// it will same as the vanilla javascript document.getElementById('child1')
Enter fullscreen mode Exit fullscreen mode

let's get some hands-on with @viewChild and ElementRef :

<div #child1>First Child</div>
<div #child2>Second Child</div>

<div #errors>2 Errors</div>
Enter fullscreen mode Exit fullscreen mode
import { Component, ElementRef, OnInit, ViewChild, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-dom-manipulation',
  templateUrl: './dom-manipulation.component.html',
  styleUrls: ['./dom-manipulation.component.scss']
})
export class DomManipulationComponent implements OnInit, AfterViewInit {

  message: any;

  @ViewChild('child1', {static: false}) firstChild: ElementRef;
  @ViewChild('child2', {static: false}) secondChild: ElementRef;
  @ViewChild('errors', {static: false}) errorChild: ElementRef;

  constructor() { }

  ngOnInit() {
    this.message = 'Awais Text Change.';
  }

  ngAfterViewInit() {
    // firstChild
    console.log("before change > ", this.firstChild.nativeElement.innerText);
    this.firstChild.nativeElement.innerText = this.message;
    console.log("after change > ", this.firstChild.nativeElement.innerText);

    // secondChild
    this.secondChild.nativeElement.style.background = 'red';
    this.secondChild.nativeElement.style.color = 'white';

    // error
    let splitted = this.errorChild.nativeElement.innerText.split(" ");
    console.log("splitted >", splitted);

    // constructing new DOM after splitting
    this.errorChild.nativeElement.innerHTML = `
      <div class="errors-head">
        <span class="number">${splitted[0]}</span>
        <span class="typo">${splitted[1]}</span>
      </div>
    `;
  }

}

Enter fullscreen mode Exit fullscreen mode

That's all :)

Discussion (0)