ViewChild and ContentChild
Written By: Avinash Malhotra
Updated on
Angular Component Communications also includes ViewChild and ContentChild. If any Parent Component want access of child component, then it uses ViewChild or ContentChild.
@ViewChild and @ContentChild are Decorators used to interact with child component and its elements to access data.
Any component, directive or element in template is ViewChild. Any component or element which is projected in template is ContentChild.
ViewChild
@ViewChild Decorator is used to access component, directive or element in parent component. Lets understand this by using a parent component app-component and a child component card-component.
parent component
We have a parent component app-component with following code in example.
<!--app.component.ts-->
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
imports: [],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'myApp';
msg="";
}
<!--app.component.html-->
<h1>{{title}}</h1>
<app-card [message]="msg">Message is {{message}}</app-card>
Child component
The child component name is card-component.
<!--card.component.ts-->
import { Component } from '@angular/core';
@Component({
selector: 'app-card',
standalone: true,
imports: [],
templateUrl: './card.component.html',
styleUrl: './card.component.css'
})
export class CardComponent {
@Input() message:string="";
}
<!--card.component.html-->
<p>Message is {{message}}</p>
Use View Child
Import ViewChild in app component. Use @ViewChild Decorator in app component. To check View Child data, use ngAfterViewInit life cycle hook.
_CardComponent {message: 'Hello There ', x: 3, y: 10, __ngContext__: 1}
<!--app.component.ts-->
import { Component, ViewChild } from '@angular/core';
import { CardComponent } from "./card/card.component";
@Component({
selector: 'app-root',
standalone: true,
imports: [CardComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'myApp';
msg="";
@ViewChild(CardComponent) messageViewChild: CardComponent | undefined;
ngAfterViewInit(){
console.log( this.messageViewChild );
}
ngOnInit(){
this.msg="Hello There ";
}
}
ViewChildren
ViewChildren is used to get QueryList of elements or directives. Import ViewChildren in app component. Use @ViewChildren Decorator in app component. To check View Children output, use ngAfterViewInit life cycle hook.
_QueryList {_emitDistinctChangesOnly: true, dirty: false, _onDirty: undefined, _results: Array(1), _changesDetected: true, …}
<!--app.component.ts-->
import { Component, ViewChildren } from '@angular/core';
import { CardComponent } from "./card/card.component";
@Component({
selector: 'app-root',
standalone: true,
imports: [CardComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'myApp';
msg="";
@ViewChildren(CardComponent) messageViewChild: CardComponent | undefined;
ngAfterViewInit(){
console.log( this.messageViewChild );
}
ngOnInit(){
this.msg="Hello There ";
}
}
ContentChild
@ContentChild Decorator is used to access content in <ng-content>. Any element or component projected inside <ng-content> becomes ContentChild.
App Component
<!--app.component.ts-->
import { Component, ContentChild } from '@angular/core';
import { CardComponent } from "./card/card.component";
@Component({
selector: 'app-root',
standalone: true,
imports: [ CardComponent, ContentChild],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'myApp';
@ContentChild(CardComponent) messageViewChild: CardComponent | undefined;
ngAfterContentInit(){console.log( this.messageViewChild );}
ngOnInit(){this.msg="Hello There"}
}
Add content for projection
<app-card>
in parent component has heading and paragraph.
<!--app.component.html-->
<h1>{{title}}</h1>
<app-card>
<h2>Card Heading</h2>
<p>Card Paragraph</p>
</app-card>
Project content in child component
ng-content
with select="h2"
wil project h2 only. To project paragraph in another ng-content
, use code select="p"
.
<!--card.component.html-->
<ng-content></ng-content>