eneoes
eneoes

Reputation: 176

@Input: Two way data binding not working

I am trying to replicate this: http://plnkr.co/edit/OB2YTMJyeY3h9FOaztak?p=preview (this plunker is the example that works, and I want to get the same result but with my code, that isn't working)

==================================================================

I have this simple two way binding, I am trying to update a string property such on the parent as on the child

The problem: when clicking "update from parent", both bindings update. But when clicking "update from child", only the childs updates!

This seems very simple, what can I be doing wrong?

(Note: I used angular CLI for running up the project)

==================================================================

Parent component:

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

@Component({
  selector: 'app-my-dad',
  templateUrl: './my-dad.component.html',
  styleUrls: ['./my-dad.component.css']
})
export class MyDadComponent {

  parentModel: string;

  constructor() {}

  updateModel(){
    this.parentModel += ' parent';
  }
}

Parent template

<h2>Parent: {{ parentModel }} </h2> 
<button (click)="updateModel()"> update from parent </button>

<app-my-child [(model)]="parentModel"></app-my-child>

Child component

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

@Component({
  selector: 'app-my-child',
  templateUrl: './my-child.component.html',
  styleUrls: ['./my-child.component.css']
})
export class MyChildComponent {

  @Input() model: string;

  constructor() { }

  updateModel(){
    this.model += ' child';
  }
}

Child template:

<h2>Child: {{ model }} </h2>
<button (click)="updateModel()"> update from child </button>

Upvotes: 14

Views: 23588

Answers (2)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657048

For two-way-binding using the [(xxx)] (banana-in-a-box) syntax, you need an @Input() and an @Output() with matching names like:

@Input() myProp:String;
@Output() myPropChange:EventEmitter<String> = new EventEmitter<String>();

See also the guide https://angular.io/docs/dart/latest/guide/template-syntax.html#!#two-way

For two-way-binding with ngModel to work, your component needs to implement ControlValueAccessor.

See also:

Upvotes: 24

Dame Lyngdoh
Dame Lyngdoh

Reputation: 352

To give a summarized elaboration to @Gunter above:

  1. Child component must have a matching EventEmitter property type with the same data-type generic and decorated with @Output()
  2. There must be call to emit method of the above property. This call is usually made in a method which changes the value of the child property.

So, your code must have:

  1. @Output() modelChange: EventEmitter<String> = new EventEmitter<String>(); in the child component.
  2. this.modelChange.emit(model); (call to emit method) in the updateModel() method of the child component.

Upvotes: 3

Related Questions