Home  >  Angular 4

Angular 2 @ViewChild() Example

By Arvind Rai, May 04, 2017
This page will walk through angular 2 @ViewChild() example. @ViewChild() decorator configures a view query. @ViewChild() decorator can be used to get the first element or the directive matching the selector from the view DOM. @ViewChild() provides the instance of another component or directive in a parent component and then parent component can access the methods and properties of that component or directive. In this way using @ViewChild() a components can communicate with a component or directive. In a parent component we can use @ViewChild() for components, directives and template reference variable with ElementRef or TemplateRef. To use @ViewChild() we need to pass child component name or directive name or template variable as an argument.
1. Suppose we have a component named as StopwatchComponent then within a parent component, we use it as follows.
@ViewChild(StopwatchComponent)
private stopwatchComponent: StopwatchComponent;	
The selector of the StopwatchComponent will be used in parent component HTML template.
2. Now suppose we have a directive CpColorDirective, then we use it as follows.
@ViewChild(CpColorDirective)
private cpColorDirective: CpColorDirective; 
The selector name of directive CpColorDirective will be used in host element of DOM layout in parent component HTML template.
3. Now if we have a template reference variable defined in parent component as given below.
<input type="text" #title> 
Then we can use title template variable with @ViewChild() as given below.
@ViewChild('title') 
private elTitle : ElementRef; 
In the same way we can use TemplateRef with template reference variable. On this page we will provide @ViewChild() complete example with component, directive and template variable. We will also provide example to use multiple @ViewChild() in parent component. Now let us discuss the example one by one.

Software Used

Find the software used in our example.
1. Angular 4.0.0
2. TypeScript 2.2.0
3. Node.js 6.10.1
4. Angular CLI 1.0.0
5. Angular Compiler CLI 4.0.0

Project Structure

Find the project structure.
angular-demo
|
|--src
|   |
|   |--app 
|   |   |
|   |   |--cpcolor.directive.ts
|   |   |--cpcolor-parent.component.ts
|   |   |--cptheme.component.ts
|   |   |--number.component.ts
|   |   |--number-parent.component.ts
|   |   |--stopwatch.component.ts
|   |   |--stopwatch-parent.component.ts
|   |   |--ui-element.component.ts
|   |   |--cpcolor-parent.component.html
|   |   |--cptheme.component.html
|   |   |--number-parent.component.html
|   |   |--stopwatch-parent.component.html
|   |   |--ui-element.component.html
|   |   |
|   |   |--app.component.ts
|   |   |--app.module.ts 
|   | 
|   |--main.ts
|   |--index.html
|   |--styles.css
|
|--node_modules
|--package.json 

@ViewChild() using Component

@ViewChild() can be used for component communication. A component will get instance of another component inside it using @ViewChild(). In this way parent component will be able to access the properties and methods of child component. The child component selector will be used in parent component HTML template. Now let us discuss example.

1. Number example

In this example we will increase and decrease the counter using two buttons. The counter will be from a child component. Increase and decrease button will be inside parent component. We will communicate parent and child components using @ViewChild() decorator.
First of all we will create a component where we will write methods to increase and decrease counter.
number.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-number',
  template: '<b>{{message}}</b>'
})
export class NumberComponent {
	message:string ='';
	count:number = 0;
	increaseByOne() {
	   this.count = this.count + 1;
	   this.message = "Counter: " + this.count;
	}
	decreaseByOne() {
	   this.count = this.count - 1;
	   this.message = "Counter: " + this.count;
	}
} 
Now we will create the instance of NumberComponent in our parent component using @ViewChild().
number-parent.component.ts
import { Component, ViewChild } from '@angular/core';
import { NumberComponent } from './number.component';

@Component({
  selector: 'app-number-parent',
  templateUrl: './number-parent.component.html'
})
export class NumberParentComponent {
    @ViewChild(NumberComponent)
    private numberComponent: NumberComponent;
    increase() {
       this.numberComponent.increaseByOne();
    }
    decrease() {
       this.numberComponent.decreaseByOne();
    }
} 
We will observe that we are able to access the methods of NumberComponent in NumberParentComponent. We will use selector of NumberComponent in HTML template of NumberParentComponent.
number-parent.component.html
<h3>@ViewChild using Component</h3>
Number Example:
<button type="button" (click)="increase()">Increase</button>
<button type="button" (click)="decrease()">Decrease</button>
<br/><br/>
<app-number></app-number> 
As usual both components NumberComponent and NumberParentComponent need to be configured in @NgModule in application module.
Find the print screen.
Angular 2 @ViewChild() Example

2. Stopwatch example

In this example we will create a simple stopwatch. We will create two components, one of which will contain the functionality of stopwatch and second component will instantiate first component using @ViewChild() decorator. Find the component that will contain the functionality of simple stopwatch.
stopwatch.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-stopwatch',
  template: '<h2>{{counter}}</h2>'
})
export class StopwatchComponent {
	shouldRun:boolean = false;
	counter:number = 0;
	start() {
	      this.shouldRun = true;
	      let interval = setInterval(() =>
  	        {  
		    if(this.shouldRun === false){
			   clearInterval(interval);
		    }
		    this.counter = this.counter + 1;			
	        }, 1000);
	}
	stop() {
	      this.shouldRun = false;
	}
} 
Now we will instantiate the above component using @ViewChild() in the following component.
stopwatch-parent.component.ts
import { Component, ViewChild } from '@angular/core';
import { StopwatchComponent } from './stopwatch.component';

@Component({
     selector: 'app-stopwatch-parent',
     templateUrl: './stopwatch-parent.component.html'
})
export class StopwatchParentComponent {
        @ViewChild(StopwatchComponent)
        private stopwatchComponent: StopwatchComponent;
	startStopwatch() {
           this.stopwatchComponent.start();
	}
	stopStopwatch() {
           this.stopwatchComponent.stop();
	}
} 
We observe that we are able to access the methods of StopwatchComponent in StopwatchParentComponent. Now use the selector of StopwatchComponent in the HTML template of StopwatchParentComponent.
stopwatch-parent.component.html
<h3>@ViewChild using Component</h3>
Stopwatch Example: 
<button type="button" (click)="startStopwatch()">Start</button>
<button type="button" (click)="stopStopwatch()">Stop</button>
<br/>
<app-stopwatch></app-stopwatch> 
Find the print screen.
Angular 2 @ViewChild() Example

@ViewChild() using Directive

@ViewChild() can instantiate a directive within a component and in this way the component will be able to access the directive methods. Here we will create a directive that will contain the methods to change the text color of the host element of DOM layout. Find the directive.
cpcolor.directive.ts
import { Directive, ElementRef, AfterViewInit } from '@angular/core';

@Directive({ 
     selector: '[cpColor]' 
})
export class CpColorDirective implements AfterViewInit{
    constructor(private elRef: ElementRef) {
    }
    ngAfterViewInit() {
	   this.elRef.nativeElement.style.color = 'red';
    }
    change(changedColor: String) {
	   this.elRef.nativeElement.style.color = changedColor;
    }
} 
AfterViewInit: It is the lifecycle hook that is called after a component view has been fully initialized. To use AfterViewInit, our class will implement it and override its method ngAfterViewInit().

Now create the component, that will instantiate CpColorDirective and access its methods.
cpcolor-parent.component.ts
import { Component, ViewChild } from '@angular/core';
import { CpColorDirective } from './cpcolor.directive';

@Component({
    selector: 'app-cpcolor-parent',
    templateUrl: './cpcolor-parent.component.html'
})
export class CpColorParentComponent {
    @ViewChild(CpColorDirective)
    private cpColorDirective: CpColorDirective;
    changeColor(color: string) {
        this.cpColorDirective.change(color);
    }
} 
In the HTML template of component a host element will use directive.
cpcolor-parent.component.html
<h3>@ViewChild using Directive</h3>
Color Example:
<p cpColor>Change my Color </p>
<div>
  Change Color:
  <input type="radio" name="rad" (click)= "changeColor('green')"> Green
  <input type="radio" name="rad" (click)= "changeColor('cyan')"> Cyan
  <input type="radio" name="rad" (click)= "changeColor('blue')"> Blue
</div> 
As usual both component and directive need to be configured in @NgModule in application module.
Find the print screen.
Angular 2 @ViewChild() Example

@ViewChild() with Template Variable using ElementRef to access Native Element

@ViewChild() can instantiate ElementRef corresponding to a given template reference variable. The template variable name will be passed in @ViewChild() as an argument. In this way component will be able to change the appearance and behavior of element of given template variable. Find the HTML template.
cptheme.component.html
<h3>@ViewChild with Template Variable using ElementRef to access Native Element </h3>
<div>
   Name: <input type="text" #name> <br/>
   City: <input type="text" #city>  
</div> 
In the above HTML template, we have two input boxes and their template reference variables are #name and #city. We will instantiate corresponding ElementRef using @ViewChild() as given below in the component.
cptheme.component.ts
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
    selector: 'app-cptheme',
    templateUrl: './cptheme.component.html'
})
export class CpThemeComponent implements AfterViewInit {
        @ViewChild('name') 
	private elName : ElementRef;
	@ViewChild('city') 
	private elCity : ElementRef;
	
	ngAfterViewInit() {
	   this.elName.nativeElement.style.backgroundColor = 'cyan';
	   this.elName.nativeElement.style.color = 'red';	   
	   this.elCity.nativeElement.style.backgroundColor = 'cyan';
	   this.elCity.nativeElement.style.color = 'red';	   	   
    }
}  
Find the print screen.
Angular 2 @ViewChild() Example

Using Multiple @ViewChild()

A component can use multiple @ViewChild() decorator. We have already seen in the previous example of @ViewChild() with template variable where we are using multiple @ViewChild() decorator. Here we will combine all our above components and directive and template variable for multiple @ViewChild() decorator demo in a parent component.
ui-element.component.ts
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { NumberComponent } from './number.component';
import { StopwatchComponent } from './stopwatch.component';
import { CpColorDirective } from './cpcolor.directive';

@Component({
    selector: 'app-ui-element',
    templateUrl: './ui-element.component.html'
})
export class UIElementComponent implements AfterViewInit {
        @ViewChild(NumberComponent)
        private numberComponent: NumberComponent;
        @ViewChild(StopwatchComponent)
        private stopwatchComponent: StopwatchComponent;		
        @ViewChild(CpColorDirective)
        private cpColorDirective: CpColorDirective;
	@ViewChild('title') 
	private elTitle : ElementRef;
	
	ngAfterViewInit() {
	   this.elTitle.nativeElement.style.backgroundColor = 'cyan';
	   this.elTitle.nativeElement.style.color = 'red';	   	
	}
	increase() {
           this.numberComponent.increaseByOne();
	}
	decrease() {
           this.numberComponent.decreaseByOne();
	}
	startStopwatch() {
           this.stopwatchComponent.start();
	}
	stopStopwatch() {
           this.stopwatchComponent.stop();
	}	
	changeColor(color: string) {
           this.cpColorDirective.change(color);
	}	
} 
Find the HTML template.
ui-element.component.html
<h2> Using Multiple @ViewChild </h2>
<b>1. Number Example<br/>
<button type="button" (click)="increase()">Increase</button>
<button type="button" (click)="decrease()">Decrease</button>
<br/><br/>
<app-number></app-number>

<br/><b>2. Stopwatch Example </b><br/>
<button type="button" (click)="startStopwatch()">Start</button>
<button type="button" (click)="stopStopwatch()">Stop</button>
<br/>
<app-stopwatch></app-stopwatch>

<b>3. Color Example </b><br/>
<p cpColor>Change my Color </p>
<div>
  Change Color:
  <input type="radio" name="rad" (click)= "changeColor('green')"> Green
  <input type="radio" name="rad" (click)= "changeColor('cyan')"> Cyan
  <input type="radio" name="rad" (click)= "changeColor('blue')"> Blue
</div>
<br/><b>4. Title: <input type="text" #title>  

Application Component and Module

app.component.ts
import { Component } from '@angular/core';

@Component({
   selector: 'app-root',
   template: `
	     <app-number-parent></app-number-parent>
	     <app-stopwatch-parent></app-stopwatch-parent>
	     <app-cpcolor-parent></app-cpcolor-parent>
	     <app-cptheme></app-cptheme>			   
	     <app-ui-element></app-ui-element>
             `
})
export class AppComponent { 
} 
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';
import { NumberComponent }  from './number.component';
import { NumberParentComponent }  from './number-parent.component';
import { StopwatchComponent }  from './stopwatch.component';
import { StopwatchParentComponent }  from './stopwatch-parent.component';
import { CpColorDirective }  from './cpcolor.directive';
import { CpColorParentComponent }  from './cpcolor-parent.component';
import { CpThemeComponent }  from './cptheme.component';
import { UIElementComponent }  from './ui-element.component';

@NgModule({
  imports: [     
        BrowserModule
  ],
  declarations: [
        AppComponent,
	NumberComponent,
	NumberParentComponent,
	StopwatchComponent,
	StopwatchParentComponent,
	CpColorDirective,
	CpColorParentComponent,
        CpThemeComponent,		
	UIElementComponent
  ],
  bootstrap: [
        AppComponent
  ]
})
export class AppModule { } 

Run Application

To test the application, find following steps.
1. Download source code using download link given on this page.
2. In our angular CLI application, replace src folder.
3. Run ng serve command.
4. Now access the URL http://localhost:4200 . Find the print screen.
Angular 2 @ViewChild() Example

Reference

Angular @ViewChild()

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
FIND MORE TUTORILAS








Copyright ©2017 concretepage.com, all rights reserved |Privacy Policy | Contact Us