Forward Advance Learning

Angular 2 Data Binding with ES6

tl;dr: Any attributes of our component are available in the component template. These are plain old attributes of the component. Bindings are live, so whenever an attribute of the component updates, the template will be automatically updated to match.

Data binding

Your component template is automatically bound to your component class. Any attributes you create on your component class are available in the template. The component class acts a ViewModel, a model that specifically holds data for the view.

We bind with curly braces {{}}

We have a range of template binding options in Angular 2, the simplest uses the curly brace syntax, like so:

<div>Hello {{dinosaurName}}</div>

Let's wrap that up in an app component:

var AppComponent = ng.core
.Component({
selector: 'app',
template: '<h1>Hello {{dinosaurName}}</h1>'
})
.Class({
constructor: function() {
this.dinosaurName = "Liopleurodon";
}
});

http://codepen.io/superluminary/pen/GoYaYa?editors=1010

Including Expressions

We can include expressions in our curly braces, for example we can do maths or string concatenation.

<div>1 + 1 = {{1 + 1}}</div>
<div>{{"Hello " + "World"}}</div>

Calling Functions in a binding

We can call functions from our binding, provided they are assigned as attributes of the component.

var AppComponent = ng.core
.Component({
selector: "app",
template: `
Has Pet?: {{hasPet()}}
`
})
.Class({
constructor: function() {
this.dog = true;
this.cat = false;
this.hasPet = function() {
return this.dog || this.cat
};
}
});

Side effects are not allowed in bound functions

A function called from a template cannot have side effects. This means you can't update other attributes of the component.

Why not? Angular 2's change detection works in a single pass. If you call a function from the template that changes a value that is referred to elsewhere, you may end up with an inconsistent result, and Angular will throw an error.

For example:

var AppComponent = ng.core
.Component({
selector: "app",
template: `
toast level: {{toast}}
Eat toast: {{eatToast(true)}}
`
})
.Class({
constructor: function() {
this.toast = 6;
this.eatToast = function() {
this.toast --;
return this.toast;
};
}
});

The value of toast is set, then later the value of toast is updated. The first value is now incorrect. If you are in development mode, Angular 2 will traverse the component tree twice and notice that it has changed, giving you a helpful warning message.

This is different to Angular 1

Angular 1 had a multipass digest. It would loop over and over, recompiling templates until the $scope hierarchy was clean. This gave guaranteed consistency at the expense of a lot of speed.

Angular 2 does away with this. Binding in Angular 2 is one-way. This means it goes in a single pass depth-first down the component tree.

Easy Exercise - seconds in a day

We are going to do a little simple binding now.

  • Create a micro app that simply outputs the number of seconds in a day. You'll need to create a component and give it an attribute: secondsInAYear.
  • Extend it to show you the number of weeks in a human lifetime of 80 years.

You can either generate these values in the component, or directly into the template.

Escape the Dungeon Exercise - Binding to a Model

Let's assume we want to create an "escape the dungeon" app. We might model a location like so:

var locationModel = {
name: "Nondescript Corridor",
description: "It is very dark. To the north you can just make out a faint glimmer of golden light.",
exits: "North"
}

Create an app component that will display this model. Bind it as an attribute of your component, then create a view to display it.

Bonus Exercise - Catpocalypse

  • Assume the universe contains exactly one cat.
  • Assume also that a cat can produce an average of 6 kittens a year, and that all kittens are female.
  • Assume that cats weight 1kg each.
  • Assume that all cats are immortal (because they should be).

Now write a component that has a function which can calculates the number of years until our combined cats outweigh a value. You will probably need a while loop for this.

  • The Empire State building weighs 331,122,430 kg.
  • The Earth weighs 5,972,000,000,000,000,000,000,000 kg

Write a template which tells us the number of years until the cats weigh more that the Empire State building and the Earth.

Further Reading