In the course of building an application, you may encounter a scenario where it would be useful to reference a parent component from a child component, such as to inspect member data or invoke public methods. In Angular 2, this is actually quite easy to accomplish.
The code, links, and a live example of this are available at .
Suppose you begin with the following ArticleComponent
:
[app/article.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article', template: ` <feedback [val]="likes"></feedback> ` }) export class ArticleComponent { likes:number = 0; incrementLikes():void { this.likes++; } }
Your objective is to implement the feedback component so that it displays the number of likes passed to it, but the parent component controls the actual like count and passes that value in.
Begin by implementing the basic structure of the child component:
[app/feedback.component.ts] import {Component, Input} from '@angular/core'; @Component({ selector: 'feedback', template: ` <h1>Number of likes: {{ val }}</h1> <button (click)="likeArticle()">Like this article!</button> ` }) export class FeedbackComponent { @Input() val:number; likeArticle():void {} }
So far, none of this should sound surprising. Clicking on the button invokes an empty method, and you want this method to invoke a method from the parent component. However, you currently lack a reference to do this. Listing the component in the child component constructor will make it available to you:
[app/feedback.component.ts] import {Component, Input} from '@angular/core'; import {ArticleComponent} from './article.component'; @Component({ selector: 'feedback', template: ` <h1>Number of likes: {{ val }}</h1> <button (click)="like()">Like this article!</button> ` }) export class FeedbackComponent { @Input() val:number; private articleComponent:ArticleComponent; constructor(articleComponent:ArticleComponent) { this.articleComponent = articleComponent; } like():void { this.articleComponent.incrementLikes(); } }
With a reference to the parent component now available, you are easily able to invoke its public method, namely incrementLikes()
. At this point, the two components should communicate correctly.
Very simply, Angular 2 recognizes that you are injecting a component that is typed in the same way as the parent, and it will provide that parent for you. This is the full parent instance, and you are free to interact with it as you would normally interact with any component instance.
Notice that it is required that you store a reference to the component inside the constructor. Unlike when you inject a service, the child component will not automatically make the ArticleComponent
instance available to you as this.articleComponent
; you need to do this manually.
An astute developer will notice that this creates a very rigid dependency from the child component to the parent component. This is indeed the case, but not necessarily a bad thing. Often, it is useful to allow components to more easily interact with each other at the expense of their modularity. And generally, this will be a judgment call on your part.
ViewChild
to reference child component object instancesContentChild
to reference child component object instances