Lesson Tuesday

In the last lesson, we learned how to add interactivity to our Angular 2 applications by triggering methods with event bindings. This type of action is known as one-way binding.

This lesson will discuss one-way data binding and explore a type of one-way data binding called property binding. Property binding allows developers to update HTML properties dynamically. We'll experiment with property binding in our To Do List application, too.

One-Way Data Binding

In one-way data binding, data flows in one direction. For instance, consider what occurs when we trigger one of our event bindings:

  1. An event binding is attached to an HTML element. It includes a target event of click and the template statement.

  2. When the target event occurs, Angular looks for the method listed in the template statement in the same component's class declaration.

  3. The logic in the template statement method runs.

We can visualize the one-way flow of data like this:

one-way-data-binding-diagram

Property Binding

There's another type of one-way data binding in Angular 2 called property binding. Property bindings are used to set a property of an HTML element in our template to the value of an expression or variable.

Essentially, property bindings can be used to add dynamic properties to any HTML elements in our template. A property binding looks like this:

<HTML element [htmlProperty] = "someMethod() or variable"> HTML element's content </HTML element>

It's easy to differentiate between property bindings and event bindings. While event bindings use (parentheses), property bindings use [square brackets].

The property binding is composed of three primary parts:

  • The HTML element it is attached to. You can add event bindings to almost any HTML tag!

  • The property we're setting dynamically. In the pseudo-code example above, it's a fictional htmlProperty property, but any valid HTML property can be changed or defined using a property binding (such as the src property on an <img> tag or a class property on a <p> tag.)

  • The template expression in quotation marks. In the example above, it's "someMethod()". But the template expression doesn't always have to be a method. It can be a dynamic variable defined on the component's class, too.

Property bindings are a one-way data binding because data only flows in one direction from the back-end of the component to the component's template view.

property-binding-diagram

However, notice that data is flowing in the opposite direction as event bindings. Here's what happens when a property binding is executed:

  1. The template loads, triggering the template expression automatically. The expression is evaluated.

  2. The result of the expression is inserted as an HTML property on whatever element the property binding was attached to.

  3. This new property changes the appearance (or even capabilities) of the HTML element.

Property Binding in To Do List

Let's add a property binding to our To Do List. We'll add a priority property to each Task that denotes how urgent it is. Then we'll change the way a Task appears to the user depending on its priority level.

First, let's add the priority property to our Task model:

app/app.component.ts
...
export class Task {
  public done: boolean = false;
  constructor(public description: string, public priority: number) {   }
}
...

Then, make sure to include it each time we call the constructor. We'll assume our priority property will contain a number between 1 and 3. 3 being the highest priority, and 1 the lowest.

app/app.component.ts
...
export class AppComponent {
  ...
  tasks: Task[] = [
    new Task('Finish weekend Angular homework for Epicodus course', 3),
    new Task('Begin brainstorming possible JavaScript group projects', 2),
    new Task('Add README file to last few Angular repos on GitHub', 2)
  ];
...

Next we'll add a property binding to the <li> that currently displays each Task.

app/app.component.ts
...
template: `
    <div class="container">
     ...
     <ul>
       <li [class]="priorityColor(currentTask)" (click)="isDone(currentTask)" *ngFor="let currentTask of tasks">{{currentTask.description}}  <button (click)="editTask()">Edit!</button></li>
     </ul>
   </div>
  `
})
...

Here, [class]="priorityColor(currentTask)" is our property binding. It's binding the <li>'s class property to the result of a method called priorityColor(). Let's define this method in our component's AppComponent class now:

app/app.component.ts
...
export class AppComponent {
...
  priorityColor(currentTask){
    if (currentTask.priority === 3){
      return "bg-danger";
    } else if (currentTask.priority === 2) {
      return  "bg-warning";
    } else {
      return "bg-info";
    }
  }
...

As you can see, the method returns a different Bootstrap class depending on the priority level of the task.

If we refresh our page, we should see different background colors on each Task based on their level of importance:

property-binding-colors-based-on-task-priority-level

You can probably see how you could add fun stylistic features to sites using property bindings. However, the most common use of property bindings is combining them with event bindings to create something called two-way data binding. In an upcoming lesson, we'll discuss two-way data binding, its uses, and how to add it to our applications.

For more information on property binding, check out the Property Binding entry of the Angular documentation.


Example GitHub Repo for Angular 2 To Do List