1

Okay the title may be a little confusing. My child component is in its own module and is using services that aren't available to the parent component.

I want to change some values in the child component on click of a button and was messing around and set something up like this.

@Component({
 selector: 'app-parent-component'
 template: `
 <button (click)="refreshData()" />
 <app-child-component> </app-child-component>
`
})
export class ParentComponent{
 refreshData() {
   ChildComponent.runRefresh()
 }
}

@Component({
 selector: 'app-child-component'
 template: ``
})
export class ChildComponent{
 static runRefresh() {
   console.log('refreshing')
   // Do things involving data on a service scoped to this component/module
 }
}

I was curious if there was something inherently wrong with this approach? Are there better ways to solve the problem. Im familiar with checking for the changes in NgOnChanges event.

I guess what i'm trying to do is call a method inside of the child component, that uses the child component resources on a scoped service, from a parent component.

Edit: Also aware of using @ViewChild and not making the child components method static. Maybe that is the only "right" way?

Petey
  • 2,819
  • 1
  • 14
  • 23
  • Only one I can think of is if you have multiple instances of the component, which of the components are you going to refresh? I think I would rather go for the component having its own way of triggering a refresh through a @Input setter or some other way. – Inge Olaisen Mar 02 '20 at 19:19
  • @IngeOlaisen refreshing is more of a refresh of the data and make a call to the api. Not actually refreshing anything in the browser. I know I can use an ViewChild and put a reference on the . Just looking for new ways – Petey Mar 02 '20 at 19:23
  • Why is `runRefresh` static? – ConnorsFan Mar 02 '20 at 19:27
  • @ConnorsFan It was just static because I was experimenting. I like your solution though. Thanks! – Petey Mar 02 '20 at 20:14
  • Does this answer your question? [Call child component method from parent class - Angular](https://stackoverflow.com/questions/38974896/call-child-component-method-from-parent-class-angular) – Leonel Thiesen Nov 23 '22 at 17:31

2 Answers2

4

If runRefresh is a public method of the child component:

export class ChildComponent{
  public runRefresh() {
    ...
  }
}

you can call it directly in the parent template by referring to the child component with the help of a template reference variable:

<button (click)="child.runRefresh()" />
<app-child-component #child></app-child-component>

See this stackblitz for a demo.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
0

The easiest way is to write a service that provide an event, emit in parent, subscribe in the childs.

Another way:

You can write a directive that provides a component reference:

import { Directive, TemplateRef } from '@angular/core';

@Directive({
  selector: '[selectordirective]',
})
export class SelectorDirective  {
  constructor(public cmpRef: ChildComponent) { }
}

Attach it to your childs:

<app-child-component selectordirective> </app-child-component>

Use ViewChild to read the reference in ParentComponent:

@ViewChild(SelectorDirective) child !: SelectorDirective;

  ngAfterViewInit() {
    child.cmpRef.runRefresh()
  }
enno.void
  • 6,242
  • 4
  • 25
  • 42