In this Angular 8/9 tutorial, we will understand how to use ElementRef
getting element reference in the document or HTML template as we use document.getElementById()
method in vanilla javascript.
# ElemementRef in detail
The ElemementRef
is a class which can wrap around a specified DOM element to enhance its properties and methods available on a native element.
By defining an element as ElemementRef we access it as a nativeElement
object.
# Using ElementRef class in Angular Typescript
Let’s check how to use ElemementRef interface in a class with the @ViewChild decorator to get element references.
You can create a new Angular application by running $ ng new angular-elementref-tutorial
or go ahead with your current project.
For online development resources, you can open the Stackblitz online development solution.
Now in the app.component.html template add the following <div>
element with a template reference variable #myDOMElement
<div #myDOMElement>
</div>
In the app.component.ts file, add following code
// app.component.ts import { Component, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = "Angular ElementRef and @ViewChild Example"; @ViewChild('myDOMElement', { static: true }) MyDOMElement: ElementRef; // If { static: true } ngOnInit() { console.log(this.MyDOMElement); this.MyDOMElement.nativeElement.innerHTML = "I am changed by ElementRef & ViewChild"; } // if { static: false } ngAfterViewInit() { console.log(this.MyDOMElement); this.MyDOMElement.nativeElement.innerHTML = "I am changed by ElementRef & ViewChild"; } }
As we are going to place some text in the <div #myDOMElement></div>
, so we need to import ElemementRef
and ViewChild
from @angular/core
Next, we will wrap the <div />
element with native methods using the template reference variable #myDOMElement
. Define it in the @ViewChild
decorator then get modified instance in the MyDOMElement
and defining it with ElemementRef
type.
@ViewChild('myDOMElement', { static: false }) MyDOMElement: ElementRef;
# How to use the static
property?
Before Angular 8 we needed to get ElemementRef
in the ngAfterViewInit()
component lifecycle hook. But now we can set static to true and get element reference in the ngOnInit()
component hook.
In latest version 9 you can remove the static property and use it in the ngAfterViewInit()
.
@ViewChild('myDOMElement') MyDOMElement: ElementRef;
ngAfterViewInit() {
console.log(this.MyDOMElement);
this.MyDOMElement.nativeElement.innerHTML = "I am changed by ElementRef & ViewChild";
}
We have added both above you can play by setting it to false, the MyDOMElement
be result is undefined.
So now as you can see we can access the innerHTML
method to set text in our div.
The following line
this.MyDOMElement.nativeElement.innerHTML = "I am changed by ElementRef & ViewChild";
is similar to the
document.getElementById('myDOMElement') = "I am changed by ElementRef & ViewChild"
which we use in native Javascript.
# How to dynamically define Template Reference Variable in Angular on a List?
There may be some situation where you want to have Template reference variables on dynamic elements like a list of items and add some sort of event listeners like (click) events etc.
In that case, the @ViewChildren
decorator in combination with QueryList
is used in the following way:
// app.component.ts import { Component, ElementRef, ViewChildren, QueryList } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { dummyList = []; title = "Angular ElementRef and @ViewChild Example"; @ViewChildren('myitems') items: QueryList<ElementRef>; constructor() { this.dummyList = [ { value: "Esteban Gutmann IV", }, { value: "Bernardo Prosacco Jr.", }, { value: "Nicholaus Kulas PhD", } ]; } getItemDetails(event, item, i) { console.log('item clicked : ', item); console.log('event : ', event); console.log('index of item : ', i); console.log('all items : ', this.items) } }
In the template, we have a list with *ngFor
a directive to iterate over dummyList
object items. There is a (click) listener which is passing the item, index and event. You can use any information required.
<div *ngFor="let item of dummyList;let i = index" #myitems>
<label (click)="getItemDetails($event,item, i)">{{ item.value }}</label>
</div>
The #myitems
template reference is used will get the reference of all elements and keep them in the QueryList with the help of @ViewChildren
decorator.
Conclusion: Here we discussed How to use ElementRef
interface and @ViewChild
decorator to get the reference of and element in DOM by using its #template reference variable.
Hi I don’t want to use click event in the @ViewChildren example above. Then could you please tell me how to get data and print in console?