docs: edit interpolation doc (#38687)

This commit edits the copy on the interpolation page.
Tightens language, clarifies headers, and streamlines text.
There are no content or code changes.

PR Close #38687
This commit is contained in:
Kapunahele Wong 2020-09-02 17:11:04 -04:00 committed by Jessica Janiuk
parent 11cd37fae3
commit 0b5b24abd7
3 changed files with 85 additions and 98 deletions

View File

@ -9,8 +9,10 @@ import { CUSTOMERS } from './customers';
}) })
export class AppComponent { export class AppComponent {
customers = CUSTOMERS; customers = CUSTOMERS;
// #docregion customer
currentCustomer = 'Maria'; currentCustomer = 'Maria';
// #enddocregion customer
title = 'Featured product:'; title = 'Featured product:';
itemImageUrl = '../assets/potted-plant.png'; itemImageUrl = '../assets/potted-plant.png';

View File

@ -1,80 +1,73 @@
# Interpolation and template expressions # Text interpolation
Interpolation allows you to incorporate calculated strings into the text Text interpolation allows you to incorporate dynamic string values into your HTML templates.
between HTML element tags and within attribute assignments. Template With interpolation, you can dynamically change what appears in an application view, such as displaying a custom greeting that includes the user's name.
expressions are what you use to calculate those strings.
<div class="alert is-helpful"> <div class="alert is-helpful">
See the <live-example></live-example> for all of See the <live-example></live-example> for all of the syntax and code snippets in this guide.
the syntax and code snippets in this guide.
</div> </div>
## Interpolation `{{...}}` ## Displaying values with interpolation
Interpolation refers to embedding expressions into marked up text. Interpolation refers to embedding expressions into marked up text.
By default, interpolation uses as its delimiter the double curly braces, `{{` and `}}`. By default, interpolation uses the double curly braces `{{` and `}}` as delimiters.
In the following snippet, `{{ currentCustomer }}` is an example of interpolation. To illustrate how interpolation works, consider an Angular component that contains a `currentCustomer` variable:
<code-example path="interpolation/src/app/app.component.ts" region="customer" header="src/app/app.component.ts"></code-example>
You can use interpolation to display the value of this variable in the corresponding component template:
<code-example path="interpolation/src/app/app.component.html" region="interpolation-example1" header="src/app/app.component.html"></code-example> <code-example path="interpolation/src/app/app.component.html" region="interpolation-example1" header="src/app/app.component.html"></code-example>
The text between the braces is often the name of a component Angular replaces `currentCustomer` with the string value of the corresponding component property.
property. Angular replaces that name with the In this case, the value is `Maria`.
string value of the corresponding component property.
In the following example, Angular evaluates the `title` and `itemImageUrl` properties to display some title text and an image.
<code-example path="interpolation/src/app/app.component.html" region="component-property" header="src/app/app.component.html"></code-example> <code-example path="interpolation/src/app/app.component.html" region="component-property" header="src/app/app.component.html"></code-example>
In the example above, Angular evaluates the `title` and `itemImageUrl` properties ## Template expressions
and fills in the blanks, first displaying some title text and then an image.
More generally, the text between the braces is a **template expression** A template **expression** produces a value and appears within double curly braces, `{{ }}`.
that Angular first **evaluates** and then **converts to a string**. Angular resolves the expression and assigns it to a property of a binding target.
The target could be an HTML element, a component, or a directive.
### Resolving expressions with interpolation
More generally, the text between the braces is a template expression that Angular first evaluates and then converts to a string.
The following interpolation illustrates the point by adding two numbers: The following interpolation illustrates the point by adding two numbers:
<code-example path="interpolation/src/app/app.component.html" region="convert-string" header="src/app/app.component.html"></code-example> <code-example path="interpolation/src/app/app.component.html" region="convert-string" header="src/app/app.component.html"></code-example>
The expression can invoke methods of the host component such as `getVal()` in Expressions can also invoke methods of the host component such as `getVal()` in the following example:
the following example:
<code-example path="interpolation/src/app/app.component.html" region="invoke-method" header="src/app/app.component.html"></code-example> <code-example path="interpolation/src/app/app.component.html" region="invoke-method" header="src/app/app.component.html"></code-example>
Angular evaluates all expressions in double curly braces, With interpolation, Angular performs the following tasks:
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**.
You appear to be inserting the result between element tags and assigning it to attributes. 1. Evaluates all expressions in double curly braces.
However, interpolation is a special syntax that Angular converts into a *property binding*. 1. Converts the expression results to strings.
1. Links the results to any adjacent literal strings.
1. Assigns the composite to an element or directive property.
<div class="alert is-helpful"> <div class="alert is-helpful">
If you'd like to use something other than `{{` and `}}`, you can You can configure the interpolation delimiter with the [interpolation](api/core/Component#interpolation) option in the `@Component()` metadata.
configure the interpolation delimiter via the
[interpolation](api/core/Component#interpolation)
option in the `Component` metadata.
</div> </div>
## Template expressions ### Syntax
A template **expression** produces a value and appears within the double Template expressions are similar to JavaScript.
curly braces, `{{ }}`. Many JavaScript expressions are legal template expressions, with the following exceptions.
Angular executes the expression and assigns it to a property of a binding target;
the target could be an HTML element, a component, or a directive.
The interpolation braces in `{{1 + 1}}` surround the template expression `1 + 1`. You can't use JavaScript expressions that have or promote side effects, including:
In the property binding,
a template expression appears in quotes to the right of the&nbsp;`=` symbol as in `[property]="expression"`.
In terms of syntax, template expressions are similar to JavaScript.
Many JavaScript expressions are legal template expressions, with a few exceptions.
You can't use JavaScript expressions that have or promote side effects,
including:
* Assignments (`=`, `+=`, `-=`, `...`) * Assignments (`=`, `+=`, `-=`, `...`)
* Operators such as `new`, `typeof`, `instanceof`, etc. * Operators such as `new`, `typeof`, or `instanceof`
* Chaining expressions with <code>;</code> or <code>,</code> * Chaining expressions with <code>;</code> or <code>,</code>
* The increment and decrement operators `++` and `--` * The increment and decrement operators `++` and `--`
* Some of the ES2015+ operators * Some of the ES2015+ operators
@ -84,92 +77,84 @@ Other notable differences from JavaScript syntax include:
* No support for the bitwise operators such as `|` and `&` * No support for the bitwise operators such as `|` and `&`
* New [template expression operators](guide/template-expression-operators), such as `|`, `?.` and `!` * New [template expression operators](guide/template-expression-operators), such as `|`, `?.` and `!`
## Expression context ## Expression context
The *expression context* is typically the _component_ instance. Interpolated expressions have a context&mdash;a particular part of the application to which the expression belongs.
In the following snippets, the `recommended` within double curly braces and the Typically, this context is the component instance.
`itemImageUrl2` in quotes refer to properties of the `AppComponent`.
In the following snippet, the expression `recommended` and the expression `itemImageUrl2` refer to properties of the `AppComponent`.
<code-example path="interpolation/src/app/app.component.html" region="component-context" header="src/app/app.component.html"></code-example> <code-example path="interpolation/src/app/app.component.html" region="component-context" header="src/app/app.component.html"></code-example>
An expression may also refer to properties of the _template's_ context An expression can also refer to properties of the _template's_ context such as a [template input variable](guide/built-in-directives#template-input-variables) or a [template reference variable](guide/template-reference-variables).
such as a template input variable,
<!-- link to built-in-directives#template-input-variables --> The following example uses a template input variable of `customer`.
`let customer`, or a template reference variable, `#customerInput`.
<!-- link to guide/template-ref-variables -->
<code-example path="interpolation/src/app/app.component.html" region="template-input-variable" header="src/app/app.component.html (template input variable)"></code-example> <code-example path="interpolation/src/app/app.component.html" region="template-input-variable" header="src/app/app.component.html (template input variable)"></code-example>
This next example features a template reference variable, `#customerInput`.
<code-example path="interpolation/src/app/app.component.html" region="template-reference-variable" header="src/app/app.component.html (template reference variable)"></code-example> <code-example path="interpolation/src/app/app.component.html" region="template-reference-variable" header="src/app/app.component.html (template reference variable)"></code-example>
The context for terms in an expression is a blend of the _template variables_, The context against which an expression evaluates is the union of the template variables, the directive's context object&mdash;if it has one&mdash;and the component's members.
the directive's _context_ object (if it has one), and the component's _members_. If you reference a name that belongs to more than one of these namespaces, Angular applies the following logic to determine the context:
If you reference a name that belongs to more than one of these namespaces,
the template variable name takes precedence, followed by a name in the directive's _context_, 1. The template variable name.
and, lastly, the component's member names. 1. A name in the directive's context.
1. The component's member names.
The previous example presents such a name collision. The component has a `customer` The previous example presents such a name collision. The component has a `customer`
property and the `*ngFor` defines a `customer` template variable. property and the `*ngFor` defines a `customer` template variable.
<div class="alert is-helpful"> <div class="alert is-helpful">
The `customer` in `{{customer.name}}` The `customer` in `{{customer.name}}` refers to the template input variable, not the component's property.
refers to the template input variable, not the component's property.
Template expressions cannot refer to anything in Template expressions cannot refer to anything in the global namespace, except `undefined`.
the global namespace, except `undefined`. They can't refer to They can't refer to `window` or `document`.
`window` or `document`. Additionally, they Additionally, they can't call `console.log()` or `Math.max()` and they are restricted to referencing members of the expression context.
can't call `console.log()` or `Math.max()` and they are restricted to referencing
members of the expression context.
</div> </div>
## Expression guidelines ## Expression best practices
When using template expressions follow these guidelines: When using template expressions, follow these best practices:
* [Simplicity](guide/interpolation#simplicity) * **Use short expressions**
* [Quick execution](guide/interpolation#quick-execution)
* [No visible side effects](guide/interpolation#no-visible-side-effects)
### Simplicity Use property names or method calls whenever possible.
Keep application and business logic in the component, where it is easier to develop and test.
Although it's possible to write complex template expressions, it's a better * **Quick execution**
practice to avoid them.
A property name or method call should be the norm, but an occasional Boolean negation, `!`, is OK. Angular executes template expressions after every [change detection](guide/glossary#change-detection) cycle.
Otherwise, confine application and business logic to the component, Many asynchronous activities trigger change detection cycles, such as promise resolutions, HTTP results, timer events, key presses and mouse moves.
where it is easier to develop and test.
### Quick execution Expressions should finish quickly to keep the user experience as efficient as possible, especially on slower devices.
Consider caching values when their computation requires greater resources.
Angular executes template expressions after every change detection cycle. * **No visible side effects**
Change detection cycles are triggered by many asynchronous activities such as
promise resolutions, HTTP results, timer events, key presses and mouse moves.
Expressions should finish quickly or the user experience may drag, especially on slower devices. According to Angular's [unidirectional data flow model](guide/glossary#unidirectional-data-flow), a template expression should not change any application state other than the value of the target property.
Consider caching values when their computation is expensive. Reading a component value should not change some other displayed value.
The view should be stable throughout a single rendering pass.
### No visible side effects <div class="callout is-important">
<header>Idempotent expressions reduce side effects</header>
A template expression should not change any application state other than the value of the An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression is free of side effects and improves Angular's change detection performance.
target property. In Angular terms, an idempotent expression always returns *exactly the same thing* until one of its dependent values changes.
This rule is essential to Angular's "unidirectional data flow" policy. Dependent values should not change during a single turn of the event loop.
You should never worry that reading a component value might change some other displayed value. If an idempotent expression returns a string or a number, it returns the same string or number if you call it twice consecutively.
The view should be stable throughout a single rendering pass. If the expression returns an object, including an `array`, it returns the same object *reference* if you call it twice consecutively.
An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression is ideal because </div>
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 event loop. <div class="alert is-important">
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.
<div class="alert is-helpful"> There is one exception to this behavior that applies to `*ngFor`.
`*ngFor` has `trackBy` functionality that can deal with changing values in objects when iterating over them.
See [*ngFor with `trackBy`](guide/built-in-directives#ngfor-with-trackby) for details.
There is one exception to this behavior that applies to `*ngFor`. `*ngFor` has `trackBy` functionality that can deal with referential inequality of objects when iterating over them. See [*ngFor with `trackBy`](guide/built-in-directives#ngfor-with-trackby) for details. </div>
</div>

View File

@ -154,7 +154,7 @@
}, },
{ {
"url": "guide/interpolation", "url": "guide/interpolation",
"title": "Interpolation", "title": "Text interpolation",
"tooltip": "An introduction to interpolation and expressions in HTML." "tooltip": "An introduction to interpolation and expressions in HTML."
}, },
{ {