In this tutorial, we’ll see how to use ElementRef
, ViewChild
decorator, and AfterViewInit
life-cycle event for accessing the DOM by example with Angular 10.
What’s ViewChild
and AfterViewInit
?
You can use ViewChild
if you need to access a child component, directive or a DOM element from an Angular parent component.
The ViewChild
decorator is the way you can achieve DOM access in Angular way. ViewChild
returns the first element that matches a given component, directive or template reference selector.
You can also have access to multiple children using ViewChildren
instead.
We can access the following elements:
- Angular directives,
- Native DOM elements: We can access native DOM elements that have a template reference variable,
- Child components from the parent.
AfterViewInit
is a
life-cycle hook that gets fired when the view corresponding to the
component is completely rendered. This can be used to safely access the
variables, directives and child components.
What’s ElementRef
?
Although you can access the DOM
using native JavaScript APIs in Angular, it’s recommended to use APIs
provided by Angular. We can access the DOM elements by using ElementRef
available from by @angular/core
.
ElementRef
allows you to access the native DOM element using the nativeElement
property. But you need to be careful when making direct DOM access in Angular.
According to Angular docs ElementRef
:
_Use this API as the last resort when direct access to DOM is needed. Permitting direct access to the DOM can make your application more vulnerable to XSS attacks.Carefully review any use of ElementRef in your code. Use templating and data-binding provided by Angular instead. Alternatively you take a look at
Renderer
which provides API that can safely be used even when direct access to native elements is not supported.Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.
Not good. But, there’s an alternative called
Renderer2
.
Angular 10 ElementRef
and ViewChild
by Example
Let’s see how to use ElementRef
and ViewChild
by example.
Accessing Native DOM Elements with Template References
Let’s get started by an example of to access a native DOM elements which has a template reference variable.
Open the src/app/app.component.ts
file and update it as follows:
import { Component, AfterViewInit, OnInit, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit, OnInit {
name = 'Angular';
@ViewChild("myimg") elm: ElementRef;
ngOnInit(){}
ngAfterViewInit(){
console.log(this.elm);
}
}
Next, open the src/app/app.component.html
file and update it as follows:
<p>
Hello Angular 10
</p>
<p>
Angular 10 ElementRef by Example
</p>
<img width="560" height="249" #myimg src="https://i.ytimg.com/vi/M9ctBliiq1A/maxresdefault.jpg"/>
Check out the example from
https://stackblitz.com/edit/angular-9-10-elementref-example.
Accessing Child Components from Parent Component
Now that we have seen how to access a native DOM element using ViewChild
, ElementRef
and ngAfterViewInit
let’s how to access child components from their parent.
We can access a child component
and call its methods or access its instance variables. Let’s suppose we
have a child component with a sayhello
method:
sayhello() {
return 'Hello from the child!';
}
We can then call the method from our parent component class using ViewChild
as follows:
import { Component,
ViewChild,
AfterViewInit } from '@angular/core';
import { MyChildComponent } from './mychild.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild(MyChildComponent) child: MyChildComponent;
}
You can call the method using child.sayHello()
syntax.
Accessing Angular Directives
Let’s suppose we have a directive called MyDirective
like this:
@Directive({
selector:'[my-directive]',
exportAs:'mydirective'
})
class MyDirective{
sayHello(param){
console.log('Hello from directive, ', param);
}
}
We can use it in our component template as follows:
<div my-directive>Angular 10!</div>
We can access the directive using ViewChild
using the following code:
// [...]
export class AppComponent{
@ViewChild(MyDirective) myDirective;
ngAfterViewInit(){
this.myDirective.sayHello('This is a parameter!');
}
}
Conclusion
In this tutorial we have seen by example how to use ViewChild
, ElementRef
and ngAfterViewInit
to access native DOM elements, child components and directives used in the parent component’s template.
Leave a Reply