//- Double underscore means don't escape var, use !{__var}.
- var __chaining_op = '<code>;</code> or <code>,</code>';
- var __new_op = '<code>new</code>';
- var __objectAsMap = 'object';
:marked
Our Angular application manages what the user sees and can do, achieving this through the interaction of a Component class instance (the *component*) and its user-facing template.
Many of us are familiar with the component/template duality from our experience with model-view-controller (MVC) or model-view-viewmodel (MVVM). In Angular, the component plays the part of the controller/viewmodel, and the template represents the view.
Let’s find out what it takes to write a template for our view. We’ll cover these basic elements of template syntax:
* [HTML](#html)
* [Interpolation](#interpolation)
* [Template expressions](#template-expressions)
* [Template statements](#template-statements)
* [Binding syntax](#binding-syntax)
* [Property binding](#property-binding)
* [Attribute, class, and style bindings](#other-bindings)
demonstrates all of the syntax and code snippets described in this chapter.
.l-main-section
:marked
## HTML
HTML is the language of the Angular template. Our [QuickStart](../quickstart.html) application has a template that is pure HTML:
code-example(language="html" escape="html").
<h1>My First Angular 2 App</h1>
:marked
Almost all HTML syntax is valid template syntax. The `<script>` element is a notable exception; it is forbidden, eliminating the risk of script injection attacks. (In practice, `<script>` is simply ignored.)
Some legal HTML doesn’t make much sense in a template. The `<html>`, `<body>`, and `<base>` elements have no useful role in our repertoire. Pretty much everything else is fair game.
We can extend the HTML vocabulary of our templates with components and directives that appear as new elements and attributes. In the following sections we are going to learn how to get and set DOM (Document Object Model) values dynamically through data binding.
Let’s turn to the first form of data binding — interpolation — to see how much richer template HTML can be.
.l-main-section
:marked
## Interpolation
We met the double-curly braces of interpolation, `{{` and `}}`, early in our Angular education.
Angular evaluates all expressions in double curly braces, converts the expression results to strings, and links them with neighboring literal strings. Finally,
it assigns this composite interpolated result to an **element or directive property**.
We appear to be inserting the result between element tags and assigning it to attributes.
It's convenient to think so, and we rarely suffer for this mistake.
Though this is not exactly true. Interpolation is a special syntax that Angular converts into a
[property binding](#property-binding), and is explained below.
But first, let's take a closer look at template expressions and statements.
<a id="template-expressions"></a>
.l-main-section
:marked
## Template expressions
A template **expression** produces a value.
Angular executes the expression and assigns it to a property of a binding target;
the target might be an HTML element, a component, or a directive.
We put a template expression within the interpolation braces when we wrote `{{1 + 1}}`.
We’ll see template expressions again in the [property binding](#property-binding) section,
appearing in quotes to the right of the `=` symbol as in `[property]="expression"`.
We write template expressions in a language that looks like #{_JavaScript}.
Many #{_JavaScript} expressions are legal template expressions, but not all.
#{_JavaScript} expressions that have or promote side effects are prohibited,
including:
* assignments (`=`, `+=`, `-=`, ...)
* !{__new_op}
* chaining expressions with !{__chaining_op}
* increment and decrement operators (`++` and `--`)
:marked
Other notable differences from #{_JavaScript} syntax include:
block notable-differences
:marked
* no support for the bitwise operators `|` and `&`
* new [template expression operators](#expression-operators), such as `|` and `?.`
h3#expression-context Expression context
block template-expressions-cannot
:marked
Perhaps more surprising, template expressions cannot refer to anything in
the global namespace. They can’t refer to `window` or `document`. They
can’t call `console.log` or `Math.max`. They are restricted to referencing
members of the expression context.
:marked
The *expression context* is typically the **component instance**, which is
the source of binding values.
When we see *title* wrapped in double-curly braces, `{{title}}`,
we know that `title` is a property of the data-bound component.
When we see *isUnchanged* in `[disabled]="isUnchanged"`,
we know we are referring to that component's `isUnchanged` property.
The component itself is usually the expression *context*, in which case
the template expression usually references that component.
The expression context can include objects other than the component.
A [template reference variable](#ref-vars) is one such alternative context object.
:marked
<a id="no-side-effects"></a>
### Expression guidelines
Template expressions can make or break an application.
Please follow these guidelines:
* [No visible side effects](#no-visible-side-effects)
* [Quick execution](#quick-execution)
* [Simplicity](#simplicity)
* [Idempotence](#idempotence)
The only exceptions to these guidelines should be in specific circumstances that you thoroughly understand.
#### No visible side effects
A template expression should not change any application state other than the value of the
target property.
This rule is essential to Angular's "unidirectional data flow" policy.
We should never worry that reading a component value might change some other displayed value.
The view should be stable throughout a single rendering pass.
#### Quick execution
Angular executes template expressions more often than we think.
They can be called after every keypress or mouse move.
Expressions should finish quickly or the user experience may drag, especially on slower devices.
Consider caching values computed from other values when the computation is expensive.
#### Simplicity
Although it's possible to write quite complex template expressions, we really shouldn't.
A property name or method call should be the norm.
An occasional Boolean negation (`!`) is OK.
Otherwise, confine application and business logic to the component itself,
where it will be easier to develop and test.
#### Idempotence
An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression is ideal because
it is free of side effects and improves Angular's change detection performance.
In Angular terms, an idempotent expression always returns *exactly the same thing* until
one of its dependent values changes.
:marked
Dependent values should not change during a single turn of the event loop.
If an idempotent expression returns a string or a number, it returns the same string or number
when called twice in a row. If the expression returns an object (including #{_an} `#{_Array}`),
it returns the same object *reference* when called twice in a row.
.l-main-section#template-statements
:marked
## Template statements
A template **statement** responds to an **event** raised by a binding target
such as an element, component, or directive.
We’ll see template statements in the [event binding](#event-binding) section,
appearing in quotes to the right of the `=` symbol as in `(event)="statement"`.
A template statement *has a side effect*.
It's how we update application state from user input.
There would be no point to responding to an event otherwise.
.l-sub-section
:marked
Responding to events is the other side of Angular's "unidirectional data flow".
We're free to change anything, anywhere, during this turn of the event loop.
:marked
Like template expressions, template *statements* use a language that looks like #{_JavaScript}.
The template statement parser is different than the template expression parser and
specifically supports both basic assignment (`=`) and chaining expressions
(with !{__chaining_op}).
However, certain #{_JavaScript} syntax is not allowed:
* !{__new_op}
* increment and decrement operators, `++` and `--`
* operator assignment, such as `+=` and `-=`
* the bitwise operators `|` and `&`
* the [template expression operators](#expression-operators)
:marked
### Statement context
As with expressions, statements can refer only to what's in the statement context — typically the
**component instance** to which we're binding the event.
block statement-context
:marked
Template statements cannot refer to anything in the global namespace. They
can’t refer to `window` or `document`. They can’t call `console.log` or
`Math.max`.
:marked
The *onSave* in `(click)="onSave()"` is sure to be a method of the data-bound component instance.
The statement context may include an object other than the component.
A [template reference variable](#ref-vars) is one such alternative context object.
We'll frequently see the reserved `$event` symbol in event binding statements,
representing the "message" or "payload" of the raised event.
### Statement guidelines
As with expressions, avoid writing complex template statements.
A method call or simple property assignment should be the norm.
Now that we have a feel for template expressions and statements,
we’re ready to learn about the varieties of data binding syntax beyond interpolation.
.l-main-section
:marked
<a id="binding-syntax"></a>
## Binding syntax: An overview
Data binding is a mechanism for coordinating what users see with application data values.
While we could push values to and pull values from HTML,
the application is easier to write, read, and maintain if we turn these chores over to a binding framework.
We simply declare bindings between binding sources and target HTML elements and let the framework do the work.
Angular provides many kinds of data binding, and we’ll discuss each of them in this chapter.
First we'll take a high-level view of Angular data binding and its syntax.
We can group all bindings into three categories by the direction in which data flows.
Each category has its distinctive syntax:
table
tr
th Data direction
th Syntax
th Binding type
tr
td One-way<br>from data source<br>to view target
td
code-example().
{{expression}}
[target] = "expression"
bind-target = "expression"
td.
Interpolation<br>
Property<br>
Attribute<br>
Class<br>
Style
tr
td One-way<br>from view target<br>to data source
td
code-example().
(target) = "statement"
on-target = "statement"
td Event
tr
td Two-way
td
code-example().
[(target)] = "expression"
bindon-target = "expression"
td Two-way
:marked
Binding types other than interpolation have a **target name** to the left of the equal sign,
either surrounded by punctuation (`[]`, `()`) or preceded by a prefix (`bind-`, `on-`, `bindon-`).
What is that target? Before we can answer that question, we must challenge ourselves to look at template HTML in a new way.
### A new mental model
With all the power of data binding and our ability to extend the HTML vocabulary
with custom markup, it is tempting to think of template HTML as *HTML Plus*.
Well, it *is* HTML Plus.
But it’s also significantly different than the HTML we’re used to.
We really need a new mental model.
In the normal course of HTML development, we create a visual structure with HTML elements, and
we modify those elements by setting element attributes with string constants.
An element property between enclosing square brackets identifies the target property. The target property in the following code is the image element’s `src` property.
The target name is always the name of a property, even when it appears to be the name of something else. We see `src` and may think it’s the name of an attribute. No. It’s the name of an image element property.
Element properties may be the more common targets,
but Angular looks first to see if the name is a property of a known directive,
Technically, Angular is matching the name to a directive [input](#inputs-outputs),
one of the property names listed in the directive’s `inputs` array or a property decorated with `@Input()`.
Such inputs map to the directive’s own properties.
:marked
If the name fails to match a property of a known directive or element, Angular reports an “unknown directive” error.
### Avoid side effects
As we've already discussed, evaluation of a template expression should have no visible side effects. The expression language itself does its part to keep us safe. We can’t assign a value to anything in a property binding expression nor use the increment and decrement operators.
Of course, our expression might invoke a property or method that has side effects. Angular has no way of knowing that or stopping us.
The expression could call something like `getFoo()`. Only we know what `getFoo()` does.
If `getFoo()` changes something and we happen to be binding to that something, we risk an unpleasant experience. Angular may or may not display the changed value. Angular may detect the change and throw a warning error. Our general advice: stick to data properties and to methods that return values and do no more.
### Return the proper type
The template expression should evaluate to the type of value expected by the target property.
Return a string if the target property expects a string.
Return a number if the target property expects a number.
Return an object if the target property expects an object.
The `hero` property of the `HeroDetail` component expects a `Hero` object, which is exactly what we’re sending in the property binding:
Interpolation handles the script tags differently than property binding but both approaches render the
content harmlessly.
figure.image-display
img(src='/resources/images/devguide/template-syntax/evil-title.png' alt="evil title made safe" width='500px')
.l-main-section
:marked
<a id="other-bindings"></a>
## Attribute, Class, and Style Bindings
The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.
### Attribute Binding
We can set the value of an attribute directly with an **attribute binding**.
.l-sub-section
:marked
This is the only exception to the rule that a binding sets a target property. This is the only binding that creates and sets an attribute.
:marked
We have stressed throughout this chapter that setting an element property with a property binding is always preferred to setting the attribute with a string. Why does Angular offer attribute binding?
**We must use attribute binding when there is no element property to bind.**
Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA),
[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG), and
table span attributes. They are pure attributes.
They do not correspond to element properties, and they do not set element properties.
There are no property targets to bind to.
We become painfully aware of this fact when we try to write something like this:
We’re binding the input box `value` to a `firstName` property, and we’re listening for changes by binding to the input box’s `input` event.
When the user makes changes, the `input` event is raised, and the binding executes the statement within a context that includes the DOM event object, `$event`.
To update the `firstName` property, we must get the changed text by following
the path `$event.target.value`.
If the event belongs to a directive (remember: components are directives), `$event` has whatever shape the directive chose to produce.
<a id="eventemitter"></a>
<a id="custom-event"></a>
### Custom Events with EventEmitter
Directives typically raise custom events with an Angular [EventEmitter](../api/core/index/EventEmitter-class.html).
A directive creates an `EventEmitter` and exposes it as a property.
The directive calls `EventEmitter.emit(payload)` to fire an event, passing in a message payload that can be anything.
Parent directives listen for the event by binding to this property and accessing the payload through the `$event` object.
Consider a `HeroDetailComponent` that presents hero information and responds to user actions.
Although the `HeroDetailComponent` has a delete button it doesn't know how to delete the hero itself.
The best it can do is raise an event reporting the user's delete request.
Here are the pertinent excerpts from that `HeroDetailComponent`:
Many DOM events, both [native](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Overview_of_Events_and_Handlers ) and [custom](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events ), bubble up their ancestor tree of DOM elements until an event handler along the way prevents further propagation.
.l-sub-section
:marked
`EventEmitter` events don’t bubble.
:marked
The result of an event binding statement determines whether
when we want to add or remove *many* CSS classes at the same time.
A good way to apply `NgClass` is by binding it to a key:value control !{__objectAsMap}. Each key of the object is a CSS class name; its value is `true` if the class should be added, `false` if it should be removed.
:marked
Consider a component method such as `setClasses` that manages the state of three CSS classes:
Learn about other special *index-like* values such as `last`, `even`, and `odd` in the [NgFor API reference](../api/common/index/NgFor-directive.html).
:marked
#### NgForTrackBy
The `ngFor` directive has the potential to perform poorly, especially with large lists.
A small change to one item, an item removed, or an item added can trigger a cascade of DOM manipulations.
For example, we could refresh the list of heroes by re-querying the server.
The refreshed list probably contains most, if not all, of the previously displayed heroes.
*We* know this because the `id` of each hero hasn't changed.
But Angular sees only a fresh list of new object references.
It has no choice but to tear down the old list, discard those DOM elements, and re-build a new list with new DOM elements.
Angular can avoid this churn if we give it a *tracking* function that tells it what we know:
that two objects with the same `hero.id` are the same *hero*. Here is such a function:
When we reviewed the `NgFor`, `NgIf`, and `NgSwitch` built-in directives, we called out an oddity of the syntax: the asterisk (`*`) that appears before the directive names.
The `*` is a bit of syntactic sugar that makes it easier to read and write directives that modify HTML layout
with the help of templates.
`NgFor`, `NgIf`, and `NgSwitch` all add and remove element subtrees that are wrapped in `<template>` tags.
We didn't see the `<template>` tags because the `*` prefix syntax allowed us to skip those tags and
focus directly on the HTML element that we are including, excluding, or repeating.
In this section we go under the hood and see how
Angular strips away the `*` and expands the HTML into the `<template>` tags for us.
:marked
### Expanding `*ngIf`
We can do what Angular does ourselves and expand the `*` prefix syntax to template syntax. Here's some code with `*ngIf`:
The template expression language employs a subset of #{_JavaScript} syntax supplemented with a few special operators
for specific scenarios. We'll cover two of these operators: _pipe_ and _safe navigation operator_.
:marked
<a id="pipe"></a>
### The pipe operator ( | )
The result of an expression might require some transformation before we’re ready to use it in a binding. For example, we might want to display a number as a currency, force text to uppercase, or filter a list and sort it.
Angular [pipes](./pipes.html) are a good choice for small transformations such as these.
Pipes are simple functions that accept an input value and return a transformed value.
They're easy to apply within template expressions, using the **pipe operator (`|`)**: