Angular 2 Two Way Data Binding Tutorial

Combine the square brackets of property binding and the parentheses of event binding to create two-way binding with ngModel.

Hello World

We start with a Hello World example to familiarise ourselves with the concept of two-way data binding.

Two-way data binding combines the square brackets of property binding with the parentheses of event binding in a single notation using the ngModel directive. Tip, to remember that the parentheses go inside the brackets, visualize a banana in a box. [()]

In this example, the name property value flows from the component to the input box as with property binding. This is why the input box contains 'World' when the page is displayed. See the application output below.

The user's changes also flow back to the component, updating the name property to the latest value, as with event binding. This is why the heading is updated as the user types a value.

hello-world.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'hello-world',
    template: `
        <div>
            <label>Name:</label>
            <input type="text" [(ngModel)]="name">
            <h1 [hidden]="!name">Hello {{name}}!</h1>
        </div>`
})
export class HelloWorldComponent {
    private name: string = 'World';
}

The Application

Here is the output from this component.

Two-way Binding Breakdown

Let's break apart the two-way binding syntax to see how it works. The highlighted code shows four different ways to perform two-way binding.

The first two examples use standard Angular property and event binding to manually keep the input fields and component data in sync. They only differ in that one uses the keyup event and the other uses input to trigger the template statement. See the property binding and event binding tutorials for more information about this type of binding syntax.

Next we bind to the ngModel property of the ngModel directive to update the contents of the input field. Conversely, the ngModelChange event takes care of setting of the value of the component property when the user changes the value in the text box.

Now we get to the familiar [(ngModel)] syntax which we saw earlier, and we finish with the canonical form of this statement using bindon-NgModel. Both will do the job so it is just a matter of choice.

two-way-binding.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'two-way-binding', 
    template: `
        <h1>
            {{person.name.forename}} {{person.name.surname}} 
            ({{person.address.street}}, {{person.address.city}}, {{person.address.country}})
        </h1>
<p> <input [value]="person.name.forename" (keyup)="person.name.forename=$event.target.value"> <input [value]="person.name.surname" (input)="person.name.surname=$event.target.value"> </p> <p> Street: <input [ngModel]="person.address.street" (ngModelChange)="person.address.street=$event"> </p> <p> City: <input [(ngModel)]="person.address.city"> </p> <p> Country: <input bindon-ngModel="person.address.country"> </p>
<p> <button (click)="reset()">Reset</button> </p> <pre> {{person | json:2}} </pre>` }) export class TwoWayBindingComponent { private person: any; constructor() { this.reset(); } private reset(): void { this.person = { name: { forename: 'John', surname: 'Doe' }, address: { street: 'Lexington Avenue', city: 'New York', country: 'USA' } } } }

The Application

Here is the output from this component.

Where Next?

To find out more about Angular and TypeScript, check out these tutorials.

  • Hello World - Implement a super-simple <hello-world> custom element using an Angular and TypeScript.
  • The Angular with TypeScript Tutorial - includes examples of components, template syntax, property binding, event binding, bootstrapping and more.
  • Configuration - Configure Angular and TypeScript to download dependencies from node modules or a CDN, and to compile the TypeScript during development or in the browser at runtime.
  • Templates - introduction to inline and external templates.
  • Interpolation - use curly braces and template expressions to output data on the page.
  • Property Binding - bind to DOM properties using square brackets and template expressions.
  • Event Binding - handle DOM events using parentheses and template statements.
  • Input Binding - bind to <input> fields such as text, textarea, checkbox, radio and select.
  • Built-in Directives - see how to use built-in directives ngIf, ngSwitch, ngFor, ngClass and ngStyle.
  • Component Input Output - use @Input and @Output to pass data in to and out of a component.
  • Angular Router - Use the Angular router to navigate between components when the user clicks a link.
  • Nested Child Routes - An example of how child routes allow navigation between multiple views when a user clicks a link in a sub-menu.