11+ Year IT Industry Experience, Working as Technical Lead with Capgemini | Consultant | Leadership and Corporate Trainer | Motivational and Technical Speaker | Career Coach | Author | MVP | Founder Of RVS Group | Trained more than 4000+ IT professionals | Azure | DevOps | ASP.NET | C# | MVC | WEB API | ANGULAR | TYPESCRIPT | MEAN | SQL | SSRS | WEB SERVICE | WCF... https://bikeshsrivastava.blogspot.in/ http://bikeshsrivastava.com/

What is The difference Between @ViewChild, @ViewChildren and @ConentChild, @ContentChildren ?

The title of this article doesn’t have quite the same air of excitement about it when compared to say Batman vs Superman, but it’s a concept I struggled with for a while and I felt that it is worthy of its own blog post.
When building an application with Ionic (or more generally, with Angular) you may come across the following annotations:
  • @ViewChild
  • @ViewChildren
  • @ContentChild
  • @ContentChildren
I think the difference between “child” and “children” is reasonably obvious, the plural form would just indicate more than one, but what is the difference between content and view? All of these perform the same general function, and that is to grab a reference to something in your template. With standard Javascript, you might do something like:

document.getElementById('some-id');
But that’s not really the “Angular way” to do it. Angular is designed to be platform agnostic (i.e. it doesn’t have to run on the web), so it’s better to avoid working directly with the DOM wherever possible. Using @ViewChildren and ContentChildren will also return a QueryList which provides an observable that you can watch for changes, so it works much more nicely in the Angular environment than using getElementById does (as tempting as that may be).
In this tutorial, we are going to briefly cover how to grab elements using @ViewChildren and @ContentChildren, and then we will walk through what exactly the difference is between the two, and when you should use one over the other.

Before We Get Started

Before you go through this tutorial, you should have at least a basic understanding of Ionic 2 concepts. You must also already have Ionic 2 set up on your machine.
If you’re not familiar with Ionic 2 already, I’d recommend reading my Ionic 2 Beginners Guide first to get up and running and understand the basic concepts. If you want a much more detailed guide for learning Ionic 2, then take a look at Building Mobile Apps with Ionic 2.
If you are unfamiliar with creating custom components in general, and do not understand concepts like @Input@Output, and content projection, then it may be worthwhile watching this video first.
How do they work?
Although they look somewhat intimidating, using these annotations to grab elements is quite straight forward. You use them to set up member variables above your constructor that you can use throughout your component.
You can supply these with either a local variable or you can provide it with the class of the component you are attempting to grab. So, you could do something like this:

@ViewChildren(Item) items;
so that you could access all of the <ion-item> elements in your template through this.items, or you could do:
@ViewChild('someVariable') something;
to grab a reference to an element that you have set up a local template variable on, like this:

<some-component #someVariable></some-component>
The basic idea is simple enough, but the distinction between @ViewChildren and @ContentChildren can be quite difficult to make at first.

When to use @ViewChildren

You should use @ViewChildren when you have added the element you are trying to grab directly to the component yourself, in other words, if the element you are grabbing is not added to the component you are working with through content projection with <ng-content>. If you are working with pages in an Ionic application, then this will likely be the most common scenario, and unless you are building your own custom components then you likely would only need to use @ViewChild and @ViewChildren.
I’m going to use an application that uses a custom component that I built recently as an example. Let’s take a look at the template for the HomePage component:
<ion-header>
    <expandable-header [scrollArea]="mycontent" headerHeight="125">
        <ion-item>
            <ion-label><ion-icon name="search"></ion-icon></ion-label>
            <ion-input type="text"></ion-input>
        </ion-item>
        <ion-item>
            <ion-label><ion-icon name="funnel-outline"></ion-icon></ion-label>
            <ion-input type="text"></ion-input>
        </ion-item>
    </expandable-header>
    <ion-navbar color="primary">
        <ion-title>
          Expandable Header
        </ion-title>
    </ion-navbar>
</ion-header>
<ion-content fullscreen #mycontent>
    <ion-card *ngFor="let test of testData">
      <ion-item>
        <ion-avatar item-left>
        </ion-avatar>
        <h2>Marty McFly</h2>
        <p>November 5, 1955</p>
      </ion-item>
      <ion-card-content>
        <p>Wait a minute. Wait a minute, Doc. Uhhh... Are you telling me that you built a time machine... out of a DeLorean?! Whoa. This is heavy.</p>
      </ion-card-content>
      <ion-row>
        <ion-col>
          <button ion-button icon-left clear small>
            <ion-icon name="thumbs-up"></ion-icon>
            <div>12 Likes</div>
          </button>
        </ion-col>
        <ion-col>
          <button ion-button icon-left clear small>
            <ion-icon name="text"></ion-icon>
            <div>4 Comments</div>
          </button>
        </ion-col>
        <ion-col center text-center>
          <ion-note>
            11h ago
          </ion-note>
        </ion-col>
      </ion-row>
    </ion-card>
</ion-content>
Everything that you see above has been added directly by me to the template, so if I want to grab any of those elements from within the context of the HomePage component, then I can do so with @ViewChild or @ViewChildren.
If I wanted to grab every <ion-item> on the page I could do so with:

@ViewChildren(Item) items;
This would return the <ion-item> elements that are inside of the <ion-content> but it will also grab the <ion-item> elements that are inside of the <expandable-header> tags. This is an important distinction, because as you will see in the next section, the elements that are inside of the <expandable-header> custom component can also be grabbed with @ContentChildren, but only from the context of the ExpandableHeader component, not the HomePage component (remember, a page in Ionic is still just a normal component). I will elaborate on this in the next section, but in this case, I have added those elements directly to the HomePage template so I can grab them with @ViewChildren.
If I just wanted to grab the <ion-content> area, I could select it in a similar way to the way that I selected the Item‘s, but I could also use the #mycontent local variable that I added by doing this:
@ViewChild('mycontent') contentArea;
or I could just do this:
@ViewChild(Content) contentArea;
since Content is the name of the class for the <ion-content> tag.

When to use @ContentChildren

You can use @ContentChildren to grab a reference to content that has been projected into a component through the use of <ng-content>. This is a subtle but important difference. If I were to try to use @ContentChildren to grab those items in the example above, by doing this:
@ContentChildren(Item) items;
It wouldn’t return any results. However, let’s consider the <expandable-header> component specifically. The template for that component looks like this:
<ng-content></ng-content>
Not much here, all it does is project whatever content is added between the <expandable-header>tags in the HomePage into this template. I haven’t added anything directly to the template here, so there is nothing to grab with @ViewChild or @ViewChildren.
However, if we look at how we were using <expandable-header> in the HomePage template:
<expandable-header [scrollArea]="mycontent" headerHeight="125">
    <ion-item>
        <ion-label><ion-icon name="search"></ion-icon></ion-label>
        <ion-input type="text"></ion-input>
    </ion-item>
    <ion-item>
        <ion-label><ion-icon name="funnel-outline"></ion-icon></ion-label>
        <ion-input type="text"></ion-input>
    </ion-item>
</expandable-header>
We have two <ion-item> elements that will be projected into the ExpandableHeader component’s template. When we were in the context of the HomePage I could grab both of these items with @ViewChildren because I added them directly to the HomePage template. If we tried to do the same from the context of the ExpandableHeader component in expandable-header.ts then we wouldn’t get any results with @ViewChildren (because these elements are not coded directly into the template for ExpandableHeader).
However, even though we haven’t added these elements directly into the template for the expandable header component, they are added through content projection. This is where @ContentChildrencomes in. If we instead do this inside of expandable-header.ts:
@ContentChildren(Item) items: any;
then we can grab a reference to those elements that are being added through content projection.

Summary

The difference between @ViewChildren and @ContentChildren is one of those concepts that will just click in your head, and once you understand that difference it’s a reasonably easy distinction to make. Getting to that point can be difficult, though, so I hope I have given a clear enough example of the difference.

You have just read an article that categorized by title Angular / Interview Question by title What is The difference Between @ViewChild, @ViewChildren and @ConentChild, @ContentChildren ?. You can bookmark this page with a URL https://bikeshsrivastava.blogspot.com/2018/01/part-58-what-is-difference-between.html. Thank You!
Author: Bikesh Srivastava - Friday, January 26, 2018

4 comments to "What is The difference Between @ViewChild, @ViewChildren and @ConentChild, @ContentChildren ?"

  1. Really Good blog post.provided a helpful information.I hope that you will post more updates like this AngularJS5 Online Training

    ReplyDelete
  2. At Coepd (Center of Excellence for Professional Development) we practice Object-Oriented Programming concepts and mentor .Net Platform, C#.NET, ADO.NET which helps the attendees to build database-driven Web applications and Web Sites successfully. We also guide the attendees to develop web-based enterprise applications using ASP.NET and Visual Studio which comforts in developing the Web Services using .Net framework in Service-oriented Architecture. The Internship Program Also covers Frontend design technologies HTML, HTML5, CSS, CSS3, XML, Bootstrap, JQuery, Angular JS, and AJAX. Our collaborative ecosystem comprising of Partnerships with Software Companies enables real time software development life cycle experience.

    http://www.coepd.com/DotnetTraining.html

    ReplyDelete
  3. Get the best programming community to learn IONIC, then click here.

    ReplyDelete

Life Is Complicated, But Now programmer Can Keep It Simple.