0

I have a click event in my parent component needs to invoke a specific function from my child component. Any help would be apreciated!

2 Answers2

2

You could do this with @ViewChild:

With type selector

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}
@Component({
  selector: 'some-cmp',
  template: '<child-cmp></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {
  @ViewChild(ChildCmp) child:ChildCmp;
  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

With string selector

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}
@Component({
  selector: 'some-cmp',
  template: '<child-cmp #child></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {
  @ViewChild('child') child:ChildCmp;
  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

You could read more in here: Call child component method from parent class - Angular And here: https://angular.io/guide/component-interaction

Joseph Arriaza
  • 12,014
  • 21
  • 44
  • 63
-1

There are a few ways to achieve this event-based method:

  1. Tracking changes via Input
  2. Subscribing to an observable
  3. Emitting an event

1. Tracking changes via Input

export class ParentComponent {
    @Output() public counter: number = 100;

    public handleClick() {
        this.counter += 1;
    }
}

export class ChildComponent implements OnChanges {
    @Input() public counter: number;

    public ngOnChanges(changes: SimpleChanges): void {
        const counterProp = nameof<ChildComponent>('counter');
        if (changes[counterProp]) {
            const count: number = changes.counterProp.currentValue as number;
            console.log(`Count is now ${count}`);
        }
    }
}

2. Subscribing to an observable

export class ParentComponent {
    private count: number;
    private counter: BehaviorSubject<number>;
    constructor(private counterService: CounterService) {
        this.counter = this.counterService.getCounter().subscribe((count: number) => {
            this.count = count;
        });
    }

    public handleClick() {
        this.counter.next(this.count + 1);
    }
}

export class ChildComponent implements OnInit {
    private count: number;

    constructor(private counterService: CounterService) {
        this.counterService.getCounter().subscribe((count: number) => {
            this.count = count;
        });
    }
}

export class CounterService {
  private counter: BehaviorSubject<number>;

  constructor() {
    this.counter = new BehaviorSubject<number>();
  }

  public getCounter(): BehaviorSubject<number> {
    return this.counter;
  }
}

3. Emitting an event

export class ParentComponent {
    private count: number = 0;
    constructor(private counterService: CounterService) {
    }

    public handleClick() {
        this.counterService.increaseCount(this.count + 1);
    }
}

export class ChildComponent implements OnInit {
    private count: number;

    constructor(private counterService: CounterService) {
        this.counterService.counter.subscribe((count: number) => {
            this.count = count;
            console.log(`Count is now ${count}`);
        });
    }
}

export class CounterService {
    public counter = new EventEmitter<number>();

    public increaseCount(count: number) {
        this.counter.emit(count);
    }
}
CodeCheshire
  • 710
  • 1
  • 8
  • 27