2

I have two shared components and I want the parent to invoke a method in its child

shared component 1 (parent)

@Component({
selector: 'parent',
template: `<div>
                <div #parentBody>
                   <ng-content select="[parentBody]"></ng-content>
                </div>
                <button (click)=" " >tell child to dance</button>
            </div>
        `,
})
export class ParentComponent {
  constructor() { }

}

shared component 2 (child)

@Component({
selector: 'child',
template: `<div>
                <p>I'm a child component</p>
           </div>
          `,
})
export class ChildComponent {
  dance() {
     alert('dancing');
  }
}

and in app component

<parent>
    <div parentBody>
       <child></child>
    </div>
<parent>

how can we communicate between the parent and child component in this case

1
  • 1
    You can use the @ContentChild decorator, juste like the @ViewChild. It allows you to have a reference to your component instance and do whatever you want with it. To have a parent reference in the child, you can use the @Host decorator on a dependency injection. Commented Jan 22, 2019 at 9:04

1 Answer 1

5

You can do it in 2 ways:

1) @Output parameter in parent component.

parent.component.ts:

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'parent',
  template: `
    <div>
      <div #parentBody>
        <ng-content select="[parentBody]"></ng-content>
      </div>
      <button (click)="dance.emit()">tell child to dance</button>
    </div>
  `
})
export class ParentComponent {
  @Output() dance = new EventEmitter();
}

app.component.html:

<parent (dance)="myChild.dance()">
    <div parentBody>
       <child #myChild></child>
    </div>
<parent>

Check this simple StackBlitz DEMO which is using @Output approach


2) @ContentChild parameter in parent component.

(Added after @trichetriche commented this question. thanks @trichetriche!)

parent.component.ts:

import { Component, Input, ContentChild } from '@angular/core';

import { IChild } from './i-child';

@Component({
  selector: 'parent',
  template: `
    <div>
      <div #parentBody>
        <ng-content select="[parentBody]"></ng-content>
      </div>
      <button (click)="onClick()">tell child to dance</button>
    </div>
  `
})
export class ParentComponent {
  @ContentChild('myChild') child: IChild;

  onClick() {
    this.child.dance();
  }
}

app.component.html:

<parent>
    <div parentBody>
       <child #myChild></child>
    </div>
<parent>

Check this simple StackBlitz DEMO which is using @ContentChild approach


Either ways are a good solution to your requirement.

Sign up to request clarification or add additional context in comments.

1 Comment

you are a hero.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.