1
votes

I am trying to use two way binding between two of my components (Parent and Child component) and trying to detect the changes caused by this in ngOnChanges of both of the components. I am able to trigger ngOnChanges of Child component (Test Component) by changing input/output property of Parent component (App Component). However, I am not able to trigger ngOnChanges of Parent component by changing two way bound property in Child component.

Working Plunker can be found here: https://plnkr.co/edit/AGh6EM9l9ENMufb9JWPW?p=preview

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

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>
              <h3>Two Way Parent - {{twoWaySend}} </h3>

              <button (click) =  "oneWayButtonPressed()">Increase oneWay from Parent</button>
              <button (click) = "twoWayButtonPressed()">Increase TwoWay from Parent</button>  
                <test-component [oneWayReceive] = 'oneWaySend' 
              [(twoWayReceive)] = 'twoWaySend'></test-component>`
})
export class AppComponent implements OnChanges{ 
  name = 'Angular';
  oneWaySend = "You shall pass";
  twoWaySend = "You shall both ways";
  counter:int = 0;
  negativeCounter:int = 0;
  oneWayButtonPressed() {
    this.oneWaySend = `${this.oneWaySend} ${++this.counter}`;
  }
  twoWayButtonPressed() {
    this.twoWaySend = `${this.twoWaySend} ${--this.negativeCounter}`;
  }
  ngOnChanges() {
    console.log('ngOnchange Parent ' + this.twoWaySend);
  }
}



@Component({
  selector: 'test-component',
  template: `<h1>TestComponent {{name}}  {{oneWayReceive}}</h1>
            <h3>Two Way Child - {{twoWayReceive}}</h3>  
            <button (click) = "twoWayButtonPressed()">Change Two Way from Child</button>`
})
export class TestComponent implements OnChange {
  @Input() oneWayReceive;
  @Input() twoWayReceive;
  @Output() twoWayReceiveChange: EventEmitter<string> = new EventEmitter<string>();
  name = 'Angular';
  negativeCounter = 0;
  ngOnChanges() {
    console.log(`OneWayReceive ${this.oneWayReceive}   TwoWayReceive ${this.twoWayReceive}`);
  }
  twoWayButtonPressed() {
    this.twoWayReceive = `${--this.negativeCounter}  ${this.twoWayReceive}`;
    this.twoWayReceiveChange.emit(this.twoWayReceive);
  }
}
3

3 Answers

0
votes

ngOnChanges is only called when a parent component passes a different value for an input of the component. You just shouldn't expect the parent component's ngOnChanges method to be called, since it doesn't have any input, nor any parent component.

0
votes

Simply you can't

"I am not able to trigger ngOnChanges of Parent component by changing two way bound property in Child component"

you can detect that only from parent to child , if you want to pass changed value or event from child to parent you have to use @Outpput or EventTrigger via Service

0
votes

Angular documentation states that, ngOnChanges is called:

when Angular (re)sets data-bound input properties

If you want to capture this update;

You can use use output/event binding explicitly instead of using [()].

[twoWayReceive]="twoWaySend" (twoWayReceiveChange)="twoWaySendChange($event)"

And output change handler in your parent component would be

toWaySendChange(value: string) {
  this.twoWaySendChange = value;
  // do things that you wanted to do in ngOnChanges
}