Angular executes the expression and assigns it to property of a binding target such
as 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 [Property Bindings](#property-binding) ,
appearing in quotes to the right of the (=) symbol as in `[property]="expression"`.
A template expression is a JavaScript-like expression. Many JavaScript expressions are legal template expressions but not all and there are a few language extensions. Notable differences include:
* Assignment is prohibited except in [Event Bindings](#event-binding).
* The `new` operator is prohibited.
* The bit-wise operators, `|` and `&`, are not supported.
* Increment and decrement operators, `++` and `--`, aren’t supported.
* [Template expression operators](#expression-operators), such as `|` and `?.`, add new meaning.
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:
* assignment (`=`)
* the `new` operator
* chaining expressions with `;` or `,`
* increment and decrement operators, `++` and `--`.
Other notable differences from JavaScript syntax include:
* no support for the bit-wise operators, `|` and `&`
* new [template expression operators](#expression-operators), such as `|` and `?.`
<a id="expression-context"></a>
### Expression Context
Perhaps more surprising, we cannot refer to anything in the global namespace.
We can’t refer to `window` or `document`. We can’t call `console.log`.
We can’t refer to `window` or `document`. We can’t call `console.log` or `Math.max`.
We are restricted to referencing members of the expression context.
The *expression context* is typically the **component instance**, the source of binding values.
The **expression context** is typically the **component instance** supporting a particular template instance.
.l-sub-section
:marked
We speak of component and template ***instances***. Angular creates multiple concrete instances from a component class and its template.
For example, we may define a component and template to display a list item and tell Angular to create new instances of that component/template pair for each item in a list. There’s a separate, independent expression context for each item in that list as well.
:marked
When we see `title` wrapped in double-curly braces, <code>{{ }}</code>.,
we know that it is a property of a parent component.
When we see `[disabled]="isUnchanged"` or `(click)="onCancel()”`,
we know we are referring to that component's `isUnchanged` property and `onCancel` method respectively.
When we see *title* wrapped in double-curly braces, <code>{{title}}</code>,
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 may include an object other than the component.
A [local template variable](#local-vars) is one such alternative context object.
A [local template variable](#local-vars) is one such supplemental context object;
we’ll discuss that option below.
<a id="no-side-effects"></a>
### Expression Guidelines
Template expressions can make or break an application.
Please follow these guidelines unless you have an exceptionally good reason to break them
in specific circumstances that you thoroughly understand.
#### No visible side-effects
Another is the **`$event`** variable that contains information about an event raised on an element;
we’ll talk about that when we consider [Event Bindings](#event-binding).
A template expression should have ***no visible side-effects***.
We're not allowed to 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.
#### Finish fast
Angular executes template expressions more often than we might think.
Expressions should finish quickly or the user experience may drag, especially on slower devices.
#### Keep them simple
Although we can write quite complex template expressions, we strongly discourage that practice.
Most readers frown on JavaScript in the HTML.
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.
#### Idempotent Expressions
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.
Dependent values should not change during a single turn of the JavaScript virtual machine.
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 a `Date` or `Array`),
it returns the same object *reference* when called twice in a row.
<a id="template-statements"></a>
.l-main-section
: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 [Event Bindings](#event-binding),
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
Although we can write quite complex template expressions, we strongly discourage that practice. Most readers frown on JavaScript in the HTML. 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.
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 JavaScript virtual machine.
:marked
Now that we have a feel for template expressions, we’re ready to learn about the varieties of data binding syntax beyond Interpolation.
Angular template statements are also written in a language that looks like JavaScript.
The template statement parser is different than the template expression parser and
specifically supports both assignment (=) and chaining expressions with semicolons (;) and commas (,).
However, certain JavaScript syntax is not allowed:
* the `new` operator
* increment and decrement operators, `++` and `--`
* bit-wise operators, `|` and `&`
* the [template expression operators](#expression-operators)
As with expressions, we cannot refer to anything in the global namespace.
We can’t refer to `window` or `document`. We can’t call `console.log` or `Math.max`.
We are restricted to referencing members of the statement context.
The **statement context** is typically the **component instance** to which we are binding an event.
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 [local template variable](#local-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.
.l-sub-section
:marked
Although we can write quite complex template statements, we strongly discourage that practice.
Most readers frown on JavaScript in the HTML.
A method call or simple property assignment should be the norm.
:marked
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 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,
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 the HTML and the data properties and let the framework do the work.
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:
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
@@ -165,8 +256,8 @@ table
td One way<br>from view target<br>to data source
td
code-example(format="" ).
(target) = "expression"
on-target = "expression"
(target) = "statement"
on-target = "statement"
td Event
tr
td Two way
@@ -176,10 +267,8 @@ table
bindon-target = "expression"
td Two-way
:marked
**Template expressions must be surrounded in quotes**
except for interpolation expressions which must not be quoted.
All binding types except interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation (`[]`, `()`) or preceded by a prefix (`bind-`, `on-`, `bindon-`).
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.
@@ -187,8 +276,8 @@ table
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”.
*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.
@@ -214,7 +303,7 @@ table
Our intuition is wrong! Our everyday HTML mental model is misleading us.
In fact, once we start data binding, we are no longer working with HTML *attributes*. We aren't setting attributes.
We are setting the *properties* of DOM elements, Components, and Directives.
We are setting the *properties* of DOM elements, components, and directives.
.l-sub-section
:marked
@@ -336,7 +425,8 @@ table
.l-main-section
:marked
## Property Binding
We write a template **Property Binding** when we want to set a property of a view element to the value of a template expression.
We write a template **Property Binding** when we want to set a property of a view element to the value of
a [template expression](#template-expressions).
The most common Property Binding sets an element property to a component property value as when
we bind the source property of an image element to the component’s `heroImageUrl` property.
People often describe Property Binding as “one way data binding” because it can flow a value in one direction, from a component’s data property to an element property.
### One-way *in*
People often describe property binding as *one way data binding* because it flows a value in one direction,
from a component’s data property into a target element property.
We cannot use property binding to pull values *out* of the target element.
We can't bind to a property of the target element to read it. We can only set it.
.l-sub-section
:marked
Nor can we use property binding to *call* a method on the target element.
If the element raises events we can listen to them with an [event binding](#event-binding).
If we must read a target element property or call one of its methods,
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 expression within a context that includes the DOM event object, `$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`.
We must follow the `$event.target.value` path to get the changed text so we can update the `firstName`
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” events up their ancestor tree of DOM elements until an event handler along the way prevents further propagation.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.