I know Angular2 doesn't have two-way data binding but is there a way to mimick the two-way data binding behavior from Angular1.x?
-
The reason that the two way data binding was eliminated is because it is a fundamentally flawed architecture, so yes you could do it but you do not want to do it. – unobf May 26 '15 at 20:34
-
Something about cycles and performance? But suppose I do want this for a special case, how would I do it? – Ronald Wildenberg May 26 '15 at 20:47
-
1I have a label somewhere on a page and a textbox that allows changing the label. If I type in the textbox, the label should change. This isn't really two-way, when I think about it... But I still don't know how to implement this... – Ronald Wildenberg May 26 '15 at 21:00
8 Answers
Note - scroll down the answer for ng-model binding
You could actually do that, just that you need to invoke internal changelistener tick (similar to digest) to update binding in the zone, You can just add a (keyup)
event for that. Similarly you could use directive bindings as well with properties
dictionary of component settings.
Example:-
<input #label (keyup)>
<!-- variable #label represented as the element itself and accessible as property on controller instance
You can even bind keyup to a function or another another function and pass value from the label property-->
Display as:
<p>{{label.value}}</P>
Parent Component has a textbox and a label.
import { Component, bootstrap} from '@angular/core';
import {Display} from 'display';
@Component({
selector: 'my-app',
template: `<p><b>Parent Component:</b><p><input #label (keyup) (change)="handleChange(label.value)">
<p>{{label.value}}</P> <display [text]="label"></display></p></p>`,
directives: [Display]
})
class MainComponent {
label: any;
constructor() {
}
handleChange(label){
this.label = label;
console.log(this.label);
}
}
Now displaying it in child component as well:
@Component({
selector: 'edit',
template: `<p><b>Child Component:</b></p>{{text.value}}`
})
export class Edit {
@Input() text:any;
}
Update - ng-model for 2-way binding
Though Angular2 is one-time bound by default, ngModel
sugar has been introduced to achieve 2-way binding. With that you could do for instance:
<input ngControl="name" [(ngModel)]="name">
Here usage of square brackets ([..]
) suggests the property binding and round brackets ((..)
) for event binding. Basically when you use ng-model
, you are enabling both the bindings ngModel
is more of an event. Behind the scenes it creates an observable event(with EventEmitter
) to track the value
changes in the bound element and update the bound property respectively.
For example:-
Include formDirectives:
import {FORM_DIRECTIVES} from '@angular/common';
and with form
<form (ngSubmit)="onSubmit()" let-f="form">
<input ngControl="name" [(ngModel)]="name">
<button>Click me and check console</button>
</form>
without form
<input [(ngModel)]="name">
<button (click)="onSubmit()">Click me and check console</button>
not necessary anymore
include formDirectives dependency in view annotation.
@Component({
template: .....,
directives: [FORM_DIRECTIVES]
})
Also read the nice write up from Victor Savkin on Two-way binding in angular2 by creating the ng-model event and how it works.

- 623,577
- 216
- 2,003
- 1,567

- 123,204
- 21
- 253
- 243
-
-
update URL for Victor Savkin post: https://vsavkin.com/angular-2-template-syntax-5f2ee9f13c6a – BlackICE Aug 06 '18 at 02:31
-
I think the child component's selector name should be 'display'. – Alessandro_Russo Feb 15 '21 at 10:42
Yes there is two-way binding in angular2. See here: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel
So, how to use it in custom components?
What I like to do is something 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 e.g. when I bind it directly to my view.

- 2,724
- 31
- 32
-
this is the sanest answer I found for this problem so far, but unfortunately, i can't set the initial value for this (if there was a selectedItem to begin with), the selectedItem is not set – Tolga E May 02 '17 at 23:01
-
Don't know if I got the problem right, but couldn't you set currentSelectedItem (event won't be emitted) or set selectedItem in ctor? – Mario Eis May 03 '17 at 11:49
-
I did try that before and unfortunately event does get emitted, so you get stuck in an infinite loop – Tolga E May 03 '17 at 14:37
-
-
1Note that the name of the output emitter is important. It must be 'selectedItemChange' for this to work. Rule is that if your input is 'x', the output emitter should be named 'xChange' for banana in a box syntax to work. I was banging my head around this until I saw this article which mentioned this fact. https://bytes.vokal.io/20160509-angular-data-binding/ – Yohan Liyanage May 10 '17 at 20:51
-
Yep, exactly. That's what's officially described in the Angular docs (see the link I provided) under "Inside [(ngModel)]" – Mario Eis May 12 '17 at 10:51
You can do this by attaching to the events on the input field and updating the internal value as is done in this example:
http://plnkr.co/edit/lOFzuWtUMq1hCnrm9tGA?p=preview
Create a component that has an internal attribute that holds the label this.label
and a callback changeLabel
that expects an event object
@Component({
selector: 'app',
templateUrl: 'bound.html'
})
class App {
label: string;
constructor() {
this.label = 'default label'
}
changeLabel(event) {
this.label = event.target.value;
}
}
bootstrap(App);
The create your template and attach the callback to the appropriate event (you could attach it to the keypress
event but then you might need a timeout. I attached it to the change
event for simplicity (which means you might need to tab off the input to see the update).
<label for="myinput">{{label}}</label>
<input id="myinput" type="text"/>
<p></p>You can change the label above by typing something below</p>
<label for="labeltext">New Label Text</label>
<input type="text" id="labeltext" (change)="changeLabel($event)"/>

- 623,577
- 216
- 2,003
- 1,567

- 7,158
- 1
- 23
- 36
There is another way to trick Angular2 into two-way binding. Don't pass a property but an object into the component. If you pass an object via one-way binding all of its properties are in fact two-way bound. It makes the component less versatile as it needs to know the object but in many cases it's still useful.
I have a component that looks like this:
import { Component, Input } from "@angular/core";
import { NgSwitch, NgSwitchWhen, NgSwitchDefault } from "@angular/common";
export class Movie
{
public Title: string;
public Rating: number;
public Seen: boolean;
}
@Component
({
selector: "hh-image-checkbox",
template: `
<div [ngSwitch]="movie.Seen">
<div *ngSwitchWhen="true">
<img src="/Content/res/CheckTrue.png" (click)="onClick()">
</div>
<div *ngSwitchDefault>
<img src="/Content/res/CheckFalse.png" (click)="onClick()">
</div>
</div>
`,
directives: [NgSwitch, NgSwitchWhen, NgSwitchDefault]
})
export class ImageCheckboxComponent
{
@Input() movie: Movie;
public onClick()
{
this.movie.Seen = !this.movie.Seen;
}
}
It is invoked like this:
<hh-image-checkbox [movie]="movie"></hh-image-checkbox>
The movie object itself is one-way bound but all of its properties can be used for two-way binding.

- 2,906
- 6
- 27
- 42
-
No need to import `NgSwitch, NgSwitchWhen, NgSwitchDefault and add them to `directives`. They are provided globally by `PLATFORM_DIRECTIVES` – Günter Zöchbauer Jun 13 '16 at 03:55
Here is a simple plunker which demonstrates one way, two way and event driven approaches in action according to Angular2 2.0.0-beta.17
Two-way Event and property
<input [(ngModel)]="name" />
One way property
<input [value]="name" />
Event driven
<input (input)="name=$event.target.value">
We can dig Angular docs for more
[UPDATE 1/26/2020]
Since Angular2 beta libs are removed from project CDN ! above plnkr link doesn't work anymore.
Use below new plnkr Angular 6+ page , I ported previous page to NPMJS, new angular edition and new plnkr!

- 5,526
- 4
- 47
- 83
From the Docs:
Two-way binding (
[(...)]
)You often want to both display a data property and update that property when the user makes changes.
On the element side that takes a combination of setting a specific element property and listening for an element change event.
Angular offers a special two-way data binding syntax for this purpose,
[(x)]
. The[(x)]
syntax combines the brackets of property binding,[x]
, with the parentheses of event binding,(x)
.[( )] = BANANA IN A BOX
Visualize a banana in a box to remember that the parentheses go inside the brackets.
For more information, see

- 48,608
- 13
- 72
- 95
Its simple, try this;
<input [(ngModel)]="property" placeholder="property Value"/>
<h1>{{property}}</h1>

- 27,261
- 3
- 21
- 29