Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting reference to child component in parent component [duplicate]

In Angular 2, I have a component that has a child component. However, I want to acquire a copy of that child component to use in the parent, to call its functions or whatever.

I found out that I could use local variables, and that way I will be able to use the component in the template. However, I don't to only use it in the template, I want to use it in the actual code of the component.

I found a way to do that, here is the child code:

//our child import {Component, OnInit, EventEmitter} from 'angular2/core'  @Component({   selector: 'my-child',   providers: [],   template: `     <div>       <h2>Child</h2>      </div>   `,   directives: [],   outputs: ['onInitialized'] })  export class Child implements OnInit{    onInitialized = new EventEmitter<Child>();    constructor() {     this.name = 'Angular2'   }    ngOnInit() {     this.onInitialized.emit(this);   } } 

Parent:

//our root app component import {Component} from 'angular2/core' import {Child} from './child'  @Component({   selector: 'my-app',   providers: [],   template: `     <div>       <h2>Hello {{name}}</h2>       <my-child (onInitialized)="func($event)"></my-child>     </div>   `,   directives: [Child] }) export class App {   constructor() {     this.name = 'Angular2'   }    func(e) {     console.log(e)    } } 

I implemented it here in this plunker. But it seems like a hack.

Isn't there a simpler way to attach the component to a variable in its parent?

like image 901
AbdulRahman AlHamali Avatar asked Mar 15 '16 17:03

AbdulRahman AlHamali


People also ask

How do you find the value of a child component in the parent component?

We can get child component values in the parent component by creating a reference to the child component using the @ref directive in the Parent component. Using the reference instance, you can access the child component values in the parent.

How do you pass data from child component to parent component?

To pass data from child to parent component in React:Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .

How do you communicate between parent and child components?

@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.


2 Answers

You can use ViewChild

<child-tag #varName></child-tag>  @ViewChild('varName') someElement;  ngAfterViewInit() {   someElement... } 

where varName is a template variable added to the element. Alternatively, you can query by component or directive type.

There are alternatives like ViewChildren, ContentChild, ContentChildren.

@ViewChildren can also be used in the constructor.

constructor(@ViewChildren('var1,var2,var3') childQuery:QueryList) 

The advantage is that the result is available earlier.

See also http://www.bennadel.com/blog/3041-constructor-vs-property-querylist-injection-in-angular-2-beta-8.htm for some advantages/disadvantages of using the constructor or a field.

Note: @Query() is the deprecated predecessor of @ContentChildren()

  • https://github.com/angular/angular/blob/2.0.0-beta.17/modules/angular2/src/core/metadata.dart#L146
  • https://github.com/angular/angular/blob/2.0.0-beta.17/modules/angular2/src/core/metadata.dart#L175

Update

Query is currently just an abstract base class. I haven't found if it is used at all https://github.com/angular/angular/blob/2.1.x/modules/@angular/core/src/metadata/di.ts#L145

like image 83
Günter Zöchbauer Avatar answered Sep 20 '22 17:09

Günter Zöchbauer


You need to leverage the @ViewChild decorator to reference the child component from the parent one by injection:

import { Component, ViewChild } from 'angular2/core';    (...)  @Component({   selector: 'my-app',   template: `     <h1>My First Angular 2 App</h1>     <child></child>     <button (click)="submit()">Submit</button>   `,   directives:[App] }) export class AppComponent {    @ViewChild(Child) child:Child;    (...)    someOtherMethod() {     this.searchBar.someMethod();   } } 

Here is the updated plunkr: http://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview.

You can notice that the @Query parameter decorator could also be used:

export class AppComponent {    constructor(@Query(Child) children:QueryList<Child>) {     this.childcmp = children.first();   }    (...) } 
like image 37
Thierry Templier Avatar answered Sep 18 '22 17:09

Thierry Templier