How to use two way data binding between components in angular 2?

To be able to use two way binding short when using your component you need to readme your output property to modelChange:

export class FormInputComponent implements DoCheck {
  @Input() model: string;
  @Output() modelChange: EventEmitter = new EventEmitter();

  ngDoCheck() {
    this.modelChange.next(this.model);
  }
}

And use it this way:

<form-input [(model)]="user.name" type="text" name="test" placeholder="This is a test" alt="A test input" label="Name"></form-input>
<form-input [(model)]="user.email" type="email" name="test" placeholder="This is a test" alt="A test input" label="Email"></form-input>
<pre>{{user.name}}</pre>

This was too long to add as a comment to Thierry's answer...

Use emit() instead of next() (which is deprecated), and only call emit(newValue) when the value of model changes. Most likely you want something like this in your FormInputComponent template:

<input [ngModel]="model" (ngModelChange)="onChanges($event)">

Then in your FormInputComponent logic:

onChanges(newValue) {
  this.model = newValue;
  this.changeModel.emit(newValue);
}

As an addition: Using ngDoCheck to emit model changes will DRASTICALLY affect performance as the new value gets emited on every check cycle, no matter if it was changed or not. And that is really often! (Try a console.log!)

So what I like to do to get a comparable convenience, but without the side effects, is something like this:

private currentSelectedItem: MachineItem;
@Output() selectedItemChange: EventEmitter<MachineItem> = new EventEmitter<MachineItem>();

@Input() set selectedItem(machineItem: MachineItem) {
    this.currentSelectedItem = machineItem;
    this.selectedItemChange.emit(machineItem); 
}

get selectedItem(): MachineItem {
    return this.currentSelectedItem; 
}

And use it like

<admin-item-list [(selectedItem)]="selectedItem"></admin-item-list>

You can also emit the new value where it is actually changed. But I find it quite convenient to do that gloabaly in a setter method and don't have to bother when I bind it directly in my view.

Tags:

Angular