Lesson Tuesday

In the last lesson, we learned how to use event bindings to trigger methods calls. We also discussed how event binding is a type of one-way data binding. In this lesson, we'll learn about property bindings, which are another type of one-way data binding. With property bindings, however, data flows in the opposite direction - from the class declaration toward the HTML template.

Property Binding

Property bindings allow us to update HTML properties in our application dynamically. We can use property bindings to set a property of an HTML element in our template to the value of an expression or variable.

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 property 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.

Here's a graphic that illustrates how data flows in one direction from the back-end of the component to the component's template view.

property-binding-diagram

Once again, 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.

Let's add a property binding to our application to illustrate how they work!

Adding Property Binding to Our Application

Let's add a property binding to our to do application. 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 we'll add the priority property to our Task model:

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

Now we need to add a priority level to each of our new tasks in the class declaration. Our priority property will contain a number between 1 and 3 with 3 being the highest priority.

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)
  ];
}
...

Let's add a property binding to the <li> that currently displays each Task.

app/app.component.html
     ...
 <ul>
   <li [class]="priorityColor(currentTask)" *ngFor="let currentTask of tasks">{{currentTask.description}}  <button (click)="editTask()">Edit!</button></li>
 </ul>

[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. However, we haven't added Bootstrap to our application yet! Let's do that now. First, we'll install it using npm:

$ npm install bootstrap --save

Note that we use the --save flag because we'd also probably want to use Bootstrap in production as well.

We also have to make a small change to our .angular-cli.json file. In the "styles" array, we need to point Angular toward the installed node module where Bootstrap is stored:

.angular-cli.json
"styles": [
  "../node_modules/bootstrap/dist/css/bootstrap.min.css",
  "styles.css"
],

Note that we are not adding Bootstrap's jQuery functionality! You are more than welcome to do so yourself; however, the focus for the next few weeks is Angular, not jQuery. Keep in mind that any Bootstrap functionality that depends on jQuery will not work unless you configure this further.

If you have the server running, you will need to stop it and run ng serve again.

Now we should see different background colors for each Task based on their level of importance:

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

You can 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 two-way data binding. In the next 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.