Angular 2 Property Binding Tutorial

Use template expressions to bind to DOM properties such as hidden and title on standard HTML elements such as div and span.

Updated Nov 2017, Angular version 5.0

Property Binding with Square Brackets

We specify one-way bindings to DOM properties using square brackets and template expressions.

The template expressions in quotes on the right of the equals are used to set the DOM properties in square brackets on the left.

For example, textContent is set to a person's name, buttons are disabled based on the sex property of person, and the src, alt and title properties of the img element are bound to properties of the person object.

innerHTML sets the HTML content of the span to a number of stars (✰ is a star as you can see in the application output below). We use [innerHTML] here rather than interpolation here because interpolation would escape the HTML. This is explained further in the Angular Interpolation tutorial.

Note that the paragraph containing the stars will be hidden if the person object has no rating.

property.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-property',
  template: `
    <h1 [textContent]="'Name: ' + person.name"></h1>

    <button (click)="person = male" [disabled]="person.sex=='m'">Male</button>
    <button (click)="person = female" [disabled]="person.sex=='f'">Female</button>

    <p><img [src]="person.photo" [alt]="person.name" [title]="person.name"></p>
    <p [hidden]="!person.rating">
      Rating: <span [innerHTML]="'&#10032;'.repeat(person.rating)"></span>
    </p>`
})
export class PropertyComponent {
  female = {
    name: 'Turanga Leela',
    sex: 'f',
    rating: 4,
    photo: 'assets/images/leela.jpg'
  };
  male = {
    name: 'Philip J. Fry',
    sex: 'm',
    photo: 'assets/images/fry.jpg'
  };
  person: any = this.female;
}

The Application

Here is the output from this component.

Clicking a button changes the person object and information on the page, such as the name and image, is automatically updated. This is due to the (one-way) flow of data from the component class to the DOM properties of elements in the template.

The buttons are automatically enabled or disabled based on person.sex, and stars are displayed if a person.rating exists, again due to property binding.

Template Expression

Let's look at some examples of the type of template expressions that can be bound to DOM properties. As the results of these expressions change, the DOM properties to which they are bound automatically change too.

Template expressions are similar to JavaScript and include features such as the ternary operator, concatenation and boolean conditions. We can call built-in methods such as repeat as well.

We can use component properties and methods including getter methods. We can also use template reference variables from other elements in the template. For example, here we use the value and valueAsNumber properties from the count variable.

expression.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-expression',
  template: `
    <h1>Expressions</h1>

    <input #count type="number" value="4" (input)="star = count.value > 5">

    <p [hidden]="!count.valueAsNumber">Rating:
      <span [title]="rating(count.value) + (star ? ' You\\'re a star!' : '')"
            [innerHTML]="symbol.repeat(count.value)">
      </span>
    </p>`
})
export class ExpressionComponent {

  star = false;

  get symbol(): string {
    return this.star ? '&#10032;' : '&#10003;';
  }

  rating(count: number): string {
    return 'Your current rating is ' + count;
  }

}

The Application

Here is the output from this component. Hover the mouse over the ✓ or ✰ to confirm that "You're a star!" is only appended to the title when the stars are displayed. Stars will be output when the value reaches six.

Binding Syntax

Let's look at the different ways we can set properties and attributes on an element.

First, setting an attribute on an element will not evaluate the template expression in quotes. This is just a standard attribute assignment using a string, and we can confirm this in the application output below where we see the 'Hello ' + name string and not Hello World.

However, when we use interpolation in the quotes (identified by the double curly braces), we are now binding to the DOM property instead, and the template expression is evaluated. This is a subtle but important difference.

Property bindings using square brackets or the bind- prefix (known as the canonical form) always interpret the string in quotes as a template expression, so there is no need to include the curly braces in this case. In fact, these last three bindings are exactly equivalent and will behave the same.

syntax.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-syntax',
  template: `
    <h1>Syntax</h1>

    <p #p1 title="'Hello ' + name">{{p1.title}}</p>
    <p #p2 title="{{'Hello ' + name}}">{{p2.title}}</p>
    <p #p3 [title]="'Hello ' + name">{{p3.title}}</p>
    <p #p4 bind-title="'Hello ' + name">{{p4.title}}</p>

    <p textContent="You won't see this">This won't change</p>
    <p textContent="{{'Hello ' + name}}">You won't see this</p>
    <p [textContent]="'Hello ' + name">You won't see this</p>
    <p bind-textContent="'Hello ' + name">You won't see this</p>

    <button (click)="name='Brave New World'">Update</button>`
})
export class SyntaxComponent {
  name = 'World';
}

Just to re-emphasise the point about attributes, attempting to set textContent to a string value here will do absolutely nothing; there is no such attribute as textContent. This is different from the title example we saw earlier which exists as an attribute and a property. The value in quotes is only evaluated as a template expression when we introduce interpolation or property binding.

The Application

Here is the output from this component. The Update button is included to show that the DOM properties are automatically updated when the name value is changed.

Attribute Binding

We've seen that we can bind to attributes using simple strings only, not template expressions. The moment we use a template expression Angular will attempt to bind to a property.

But suppose there is no equivalent property for the attribute we are trying to set; two such examples are colspan and aria-label. And suppose we need to use a template expression to bind to this value. Well in this case we must use the attr directive like this:

attribute.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-attribute',
  template: `
    <h1>Attribute</h1>

    <table #t border="1" [attr.aria-label]="'Table with ' + t.rows.length + ' rows'">
      <tr>
        <td>one</td>
        <td>two</td>
        <td>three</td>
        <td>four</td>
      </tr>
      <tr>
        <td colspan="4">Hard coded</td>
      </tr>
      <tr>
        <td [attr.colspan]="t.rows.item(0).cells.length">First row cell count</td>
      </tr>
    </table>
    <p>aria-label: {{t.getAttribute('aria-label')}}</p>`
})
export class AttributeComponent {
}

Now we are binding to attributes using template expressions.

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.
  • Event Binding - handle DOM events using parentheses and template statements.
  • Two-way Binding - combine property and event binding to create two-way binding with ngModel.
  • 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.