angular tutorials

Difference between @ViewChild and @ContentChild – Angular Example

This tutorial guides you on the difference between @ViewChild and @ContentChild with Angular Example.

Difference between @ViewChild and @ContentChild – Angular Example

Let’s see how to use @ViewChild and @ContentChild in Angular application and learn the exact different between them in the following sections.

@ViewChild

It is an angular property that configures a view query. The change detector detects the view DOM changes and when a new child matches the selector, the property will be updated. The change detector looks for the directive matching the selector in the view DOM.

To fetch local references i.e., template reference variables through ViewChild you can declare angular property of type ElementRef in your component class as shown below.

Syntax

@ViewChild('<local-reference-selector>', {static: true}) <viewchild-property-name>: ElementRef;

For example, component template.

<div class="row">
    <div class="col-xs-12">
      ----
      ----
      <label>Item Description</label>     
      <input 
          type="text" 
          class="form-control" 
          #itemDescInput>
      ----
      ----
    </div>
  </div>

Here is how you select an element in a component template. For example, component class.

export class CreateItemComponent implements OnInit {

  -----
  -----

  @ViewChild('itemDescInput', {static:true}) itemDescInput: ElementRef; 

  -----
  -----

  onAddItem(itemNameInput : HTMLInputElement) {        
    this.itemAdded.emit({      
        itemTitle: itemNameInput.value,        
        itemDesc: this.itemDescInput.nativeElement.value
    });
  }

  -----
  -----

}

Please check ViewChild in Angular 9 Example tutorial for complete example. This example demonstrates how to access or select an element in a component template using local references and @ViewChild.

@ContentChild

It is an angular property that configures a content query. It can be used to get the first element or the directive matching the selector from the content DOM.

Note, content queries are set before the ngAfterContentInit() callback is called.

Syntax

@ContentChild('<local-reference-selector>', {static: true}) <contentchild-property-name>: ElementRef;

Please check Program to select an element with @ContentChild – Example. In this example, you will learn how to use the template reference variable “#contentParagraph” to access ng-content using @ContentChild within Angular component.

App Component Template

<div class="container">
  -----
  -----
  <div class="row">
    <div class="col-xs-12">
      ------
      ------
      <app-item-element *ngFor="let elem of itemElems"
                        [itemElem] = "elem"
                        [title] = "elem.title">
                        <!-- Projecting content into component with ng-content -->
                        <p #contentParagraph>
                          <strong *ngIf="elem.type === 'item'" style="color: orange">{{ elem.desc }}</strong>
                          <em *ngIf="elem.type === 'spec'">{{ elem.spec }}</em>
                        </p>
      </app-item-element>                   
    </div>
  </div>
</div>

For example, you can access ng-content using @ContentChild in the following way.

export class ItemElementComponent implements OnInit, OnChanges, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy{
  -----
  -----
  @ViewChild('heading', {static: true}) header : ElementRef;
  @ContentChild('contentParagraph', {static: true}) paragraph : ElementRef;
  
  -----
  -----

  ngOnInit(): void {
    console.log("ngOnInit called.....");
    console.log('Header Content:' + this.header.nativeElement.textContent);
    console.log('Paragraph text Content:' + this.paragraph.nativeElement.textContent);
  }

  -----

  ngAfterContentInit(){
    console.log("ngAfterContentInit called.....");
    console.log('Paragraph text Content:' + this.paragraph.nativeElement.textContent);
  }

  -----
  -----

}

What is the difference between @ViewChild and @ContentChild ?

The ViewChild property decorator can be used to to obtain a reference to an item in the component’s template.

ContentChild is similar to the usage to ViewChild as shown in the examples above. But the major difference between @ViewChild and @ContentChild is, ContentChild used to select elements within the projected content of a component.

If you are not familiar with what is projection of content, please check Project contents into angular components using ng-content. ContentChild has some additional restrictions compared to ViewChild in the types of selectors that can be used. ContentChild only supports Component or Directive types to be used as a selector.

That’s it. You had learnt how to use @ViewChild and @ContentChild in the angular application and difference between @ViewChild and @ContentChild.

Hope it helped 🙂

References:

Leave a Reply

avatar
  Subscribe  
Notify of