Korgen
Korgen

Reputation: 5399

angular2 ngModel with value from @Input

I'm trying to use [(ngModel)] within my child-component with a string passed from my parent into my child component via @Input().

However the two-way-binding does not seem to work. The string gets passed in from the parent correctly, but when I edit it in the child the parent's value does not get updated.

What am I missing?

Parent:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <child [(value)]="name"></child>
      <p>{{name}}</p>
    </div>
  `,
})
export class App {
  name:string = 'MyValue';
  constructor() {

  }
}

Child

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

@Component({
  selector: 'child',
  template: `
    <div>
    <p>My custom input</p>
      <textarea [(ngModel)]="value"></textarea>
    </div>
  `,
})
export class Child {


  @Input() value:string;

  constructor() {

  }
}

I created a plnkr which illustrates the issue: https://plnkr.co/edit/jCF5kt73P38EFYUAZF6l

Upvotes: 5

Views: 8180

Answers (3)

Amit Chigadani
Amit Chigadani

Reputation: 29695

In continuation to @Günter Zöchbauer answer I have modified the app.ts file as well.

app.ts:

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {Child} from './child'
import {FormsModule} from "@angular/forms";

@Component({
  selector: 'my-app',
  template: `
    <div>
      <child [value]="name" (valueChange)= "updateValue($event)"></child>
      <p>{{name}}</p>
    </div>
  `,
})
export class App {
  name:string = 'MyValue';
  constructor() {

  }
   updateValue(value){
      this.name = value;
    }
}

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App, Child ],
  bootstrap: [ App ]
})
export class AppModule {}

Child

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

@Component({
  selector: 'child',
  template: `
    <div>
    <p>My custom input</p>
      <textarea [(ngModel)]="value" (ngModelChange)="update($event)"></textarea>
    </div>
  `,
})
export class Child {


  @Input() value:string;
 @Output() valueChange:EventEmitter<string> = new EventEmitter<String>();

  constructor() {

  }

  update(value) {
    this.valueChange.emit(value);
  }
}

Upvotes: 0

Aardvark
Aardvark

Reputation: 331

Yeah - @Input only works one way. When the parent changes the value of Input the child gets notified. However the parent is unaware of any changes to the child, if you are only using @Input.

Upvotes: 1

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

Reputation: 657018

You need an output to notify about changes:

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

@Component({
  selector: 'child',
  template: `
    <div>
    <p>My custom input</p>
      <textarea [(ngModel)]="value" (ngModelChange)="update($event)"></textarea>
    </div>
  `,
})
export class Child {


  @Input() value:string;
  @Output() valueChange:EventEmitter<string> = new EventEmitter<String>()

  update(value) {
    this.valueChange.emit(value);
  }

  constructor() {

  }
}

Upvotes: 6

Related Questions