Understanding how parent and child components handle an object

consider you should emit the changed value from child and also your emitter name should be [your bind var name]+'Change' so it will work:

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

@Component({
  selector: 'app-root',
  template: `<app-children [(data)]="message"></app-children>
            <div>Parent: {{message}}</div>`,
})

export class AppComponent {
  public message: string;

  ngOnInit() {
    this.message = 'Original message'
  }
}

@Component({
  selector: 'app-children',
  template: `<div>Children: {{data}}</div> 
             <a (click)="changeMessage('Children message')">Click me!</a>`
})

export class ChildComponent {
  @Input() public data: string;
  @Output() dataChange= new EventEmitter<string>();
  changeMessage(message: string) {
    this.data = message;
    this.dataChange.emit(this.data);
  }
}

check DEMO and creating custom two-way data bindings.


The answer is that it's not the same object, because you completely reassign it to the new one here:

changeMessage(message: string) {
  this.data = message;
}

If you want to see whether it changes in parent component when you change it in child component, you have to change it, not create a new one, for example:

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

@Component({
  selector: 'app-root',
  template: `<app-children [data]="data"></app-children>
            <div>Parent: {{data.message}}</div>`,
})

export class AppComponent {
  public data = { message: "" };

  ngOnInit() {
    this.data.message = 'Original message'
  }
}

@Component({
  selector: 'app-children',
  template: `<div>Children: {{data.message}}</div> 
             <a (click)="changeMessage('Children message')">Click me!</a>`
})

export class ChildComponent {
  @Input() public data: { message: string };
  changeMessage(message: string) {
    this.data.message = message;
  }
}

Demo on stackblitz. Here we pass an object (where message it's just a field) to child component, and we modify object inside the child component, and changes being reflected in both components. Despite the fact that it works, it's not recommended to change an object inside of child components, for these purposes it's better to use @Output + EventEmitters. Hope that helps.

Tags:

Angular