[Tutorial] Create your own two-way data binding in Angular

You’re probably familiar with [(ngModel)] and its world-famous “banana in a box” syntax. In this post, I’m going to explain how ngModel actually works, which will allow us to replicate its behavior in order to implement our own two-way data binding.

In the end, we‘re going to create a component that takes a message as a parameter, and that message will be our component model. We would use that component as follows:

<example-component [(message)]="title"></example-component>

Highlighted in the above code is the two-way data binding we’re looking to implement.

First, let’s dissect the “banana in the box” syntax applied to ngModel. Here is the syntax that we all know about:

<input [(ngModel)]="title" type="text">

What’s interesting is that the [()] turns out to be syntactic sugar for the following:

<input [ngModel]="title" (ngModelChange)="title= $event" type="text">

The above code is definitely more verbose but it makes perfect sense when you think about it. A two-way data-binding is really… two one-way data-bindings, right?

Now the real secret that the above example unveils is the use of the Change suffix.

Let’s apply this trick to our own example component.

First let’s create a simple component with a @Input to have a one-way data binding:

export class TwoWayDataBindingExampleComponent  {

messageValue : string;

@Input()
get message(){
return this.messageValue;
}
set message(val) {
this.messageValue = val;
}
}


There are two important things to note here. First I use a property messageValue to store the actual message. Then I expose it as message, so that I can use TypeScript getters and setters to read and set the value of messageValue.

This is a key part of the technique since our setter will have to do some more work to actually notify other components of any model update.

Here is how we implement the second one-way data-binding:

export class TwoWayDataBindingExampleComponent  {

messageValue : string;

@Output()
messageChange = new EventEmitter();

@Input()
get message(){
return this.messageValue;
}

set message(val) {
this.messageValue = val;
this.messageChange.emit(this.messageValue);
}
}


Now we have everything in place. Both the getter and setter use messageValue to read / update our data model, but the setter also notifies the rest of the world by emitting an event.

As a result, we can now have a two-way data binding applied to that component with the following syntax:

<example-component [(message)]="title"></example-component>

Wasn’t that easy? Well, it sure is once we know the trick to get there. Now you can implement two-way data-bindings in your own components!

Alain Chautard

Alain started working with Angular JS in 2011, back when version 1.0 wasn’t even released yet.

He is the organizer of the Sacramento Angular Meetup group, co-organizer of the Google Developer Group chapter in Sacramento, California, and published author of the Packt video course “Migrating to Angular 2“.

One thought to “[Tutorial] Create your own two-way data binding in Angular”

  1. “Change” suffix, what an awesome trick I could not find by myself 🙂 thanks for sharing !
    PS : the fixed header of the mobile view of angulartraining is disrupting, specially when writing a comment

Comments are closed.