Sunday 11 October 2020

Angular: ViewChild and ContentChild

 Essentially ViewChild and ContentChild are used for component communication in Angular. Therefore, if a parent component wants access of child component then it uses ViewChild or ContentChild.

Any component, directive, or element which is part of a template is ViewChild and any component or element which is projected in the template is ContentChild.

ViewChild
If you want to access following inside the Parent Component, use @ViewChild decorator of Angular.
  1. Child Component
  2. Directive
  3. DOM Element
ViewChild returns the first element that matches the selector. 

Let us assume that we have a component MessageComponent as shown in the below listing:
import { ComponentInput } from '@angular/core';
@Component({
    selector: 'app-message',
    template: `
<h2>{{message}}</h2>
 
`
})
export class MessageComponent {
    @Input() messagestring;
  
}

We are using MessageComponent inside AppComponent as shown in below listing:

import { ComponentOnInit } from '@angular/core';
@Component({
  selector: 'app-root',
template:'<div><h1>Messages</h1><app-message [message]='message'></app-message></div>'
})
export class AppComponent implements OnInit {
    messageany;
    ngOnInit() {
        this.message = 'Hello World !';
    }
}

In application, you will get the output as below:

Messages
Hello World!

Here, MessageComponent has become child of AppComponent. Therefore, we can access it as a ViewChild. Definition of ViewChild is:

“The Child Element which is located inside the component template”,

Here MessageComponent is located inside template of AppComponent, so it can be accessed as ViewChild.

export class AppComponent implements OnInitAfterViewInit {
    messageany;
    @ViewChild(MessageComponentmessageViewChildMessageComponent;
  
    ngAfterViewInit() {
        console.log(this.messageViewChild);
    }
  
    ngOnInit() {
        this.message = 'Hello World !';
    }
}

We need to do following tasks:
  1. Import ViewChild and AfterViewInit from @angular/core
  2. Implement AfterViewInit life cycle hook to component class
  3. Create a variable with decorator @ViewChild
  4. Access that inside ngAfterViewInit life cycle hook
ContentChild
Let us start with understanding about ContnetChild. Any element which is located inside the template, is ContnetChild.

To understand it let us consider MessageContainerComponent.

import { Component } from '@angular/core';
@Component({
    selector: 'app-messagecontainer',
    template: `<div> 
    <h3>{{greetMessage}}</h3>
     <ng-content select="app-message"></ng-content>
    </div>`
})
export class MessageContainerComponent {
    greetMessage = 'Ignite UI Rocks!';
}

In this component, we are using Angular Content Projection.

Any element or component projected inside becomes a ContentChild. If you want to access and communicate with MessageComponent projected inside MessageContainerComponent, you need to read it as ContnetChild.

Before we go ahead and learn to use ContentChild, first see how MessageContainerComponent is used and MessageComponent is projected.

import { ComponentOnInit } from '@angular/core';
@Component({
    selector: 'app-root',
    template: `<div>
  <app-messagecontainer>
  <app-message [message]='message'></app-message>
  </app-messagecontainer>
  </div>`
})
export class AppComponent implements OnInit {
    messageany;
    ngOnInit() {
        this.message = 'Hello World !';
    }
}

As you see in the above listing that in the AppComponent, we are using MessageContainerComponent and passing MessageComponent to be projected inside it. Since MessageComponent is used in MessageContainerComponent using content projection, it becomes ContentChild.

Since, MessageComponnet is projected and being used inside template of MessageContainerComponent, it can be used as ContentChild as shown in the below listing:

import { ComponentContentChildAfterContentInit } from '@angular/core';
import { MessageComponent } from './message.component';
  
@Component({
    selector: 'app-messagecontainer',
    template: `<div> 
<h3>{{greetMessage}}</h3>
    <ng-content select="app-message"></ng-content>
    </div>  `
})
export class MessageContainerComponent implements AfterContentInit {
    greetMessage = 'Ignite UI Rocks!';
    @ContentChild(MessageComponentMessageComponnetContentChildMessageComponent;
    ngAfterContentInit() {
        console.log(this.MessageComponnetContentChild);
    }
}

We need to do the following tasks:
  • Import ContnetChild and AfterContnetInit from @angular/core
  • Implement AfterContnetInit life cycle hook to component class
  • Create a variable with decorator @ContnetChild
  • Access that inside ngAfterContnetInit life cycle hook
In the output console you will find a reference of MessageComponent, also if you can notice that __proto__ of MessageComponent is set to Object.

You can modify the ContentChild property inside ngAfterContentInit life cycle hook of the component. 

ViewChildren: Returns the specified elements or directives from the view DOM as QueryList.
The return type of ViewChildren is QueryList.
    QueryList is just a fancy name for an object that stores a list of items. What is special about this object is when the state of the application changes Angular will automatically update the object items for you.

ContentChildren: Returns the specified elements or directives from the content DOM as QueryList

ViewChildren vs ContentChildren —
  • ViewChildren don’t include elements that exist within the ng-content tag.
  • ContentChildren includes only elements that exists within the ng-content tag.


0 comments:

Post a Comment

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (43) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (47) CD (1) CI (2) CloudComputing (2) Coding (7) CQRS (1) CSS (2) Design_Pattern (6) DevOps (4) DI (3) Dotnet (8) DotnetCore (16) Entity Framework (2) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (11) microservice (3) Mongodb (1) MVC (46) NodeJS (8) React (11) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (1) UI (1) UnitTest (1) WCF (14) Web Api (15) Web Service (1) XMl (1)

Dotnet Guru Archives