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:
parent
11cd37fae3
commit
0b5b24abd7
|
@ -9,8 +9,10 @@ import { CUSTOMERS } from './customers';
|
|||
})
|
||||
export class AppComponent {
|
||||
customers = CUSTOMERS;
|
||||
|
||||
// #docregion customer
|
||||
currentCustomer = 'Maria';
|
||||
// #enddocregion customer
|
||||
|
||||
title = 'Featured product:';
|
||||
itemImageUrl = '../assets/potted-plant.png';
|
||||
|
||||
|
|
|
@ -1,80 +1,73 @@
|
|||
# Interpolation and template expressions
|
||||
# Text interpolation
|
||||
|
||||
Interpolation allows you to incorporate calculated strings into the text
|
||||
between HTML element tags and within attribute assignments. Template
|
||||
expressions are what you use to calculate those strings.
|
||||
Text interpolation allows you to incorporate dynamic string values into your HTML templates.
|
||||
With interpolation, you can dynamically change what appears in an application view, such as displaying a custom greeting that includes the user's name.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
See the <live-example></live-example> for all of
|
||||
the syntax and code snippets in this guide.
|
||||
See the <live-example></live-example> for all of the syntax and code snippets in this guide.
|
||||
|
||||
</div>
|
||||
|
||||
## Interpolation `{{...}}`
|
||||
## Displaying values with interpolation
|
||||
|
||||
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>
|
||||
|
||||
The text between the braces is often the name of a component
|
||||
property. Angular replaces that name with the
|
||||
string value of the corresponding component property.
|
||||
Angular replaces `currentCustomer` with the string value of the corresponding component property.
|
||||
In this case, the value is `Maria`.
|
||||
|
||||
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>
|
||||
|
||||
In the example above, Angular evaluates the `title` and `itemImageUrl` properties
|
||||
and fills in the blanks, first displaying some title text and then an image.
|
||||
## Template expressions
|
||||
|
||||
More generally, the text between the braces is a **template expression**
|
||||
that Angular first **evaluates** and then **converts to a string**.
|
||||
A template **expression** produces a value and appears within double curly braces, `{{ }}`.
|
||||
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:
|
||||
|
||||
<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
|
||||
the following example:
|
||||
Expressions can also invoke methods of the host component such as `getVal()` in the following 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,
|
||||
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**.
|
||||
With interpolation, Angular performs the following tasks:
|
||||
|
||||
You appear to be inserting the result between element tags and assigning it to attributes.
|
||||
However, interpolation is a special syntax that Angular converts into a *property binding*.
|
||||
1. Evaluates all expressions in double curly braces.
|
||||
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">
|
||||
|
||||
If you'd like to use something other than `{{` and `}}`, you can
|
||||
configure the interpolation delimiter via the
|
||||
[interpolation](api/core/Component#interpolation)
|
||||
option in the `Component` metadata.
|
||||
You can configure the interpolation delimiter with the [interpolation](api/core/Component#interpolation) option in the `@Component()` metadata.
|
||||
|
||||
</div>
|
||||
|
||||
## Template expressions
|
||||
### Syntax
|
||||
|
||||
A template **expression** produces a value and appears within the double
|
||||
curly braces, `{{ }}`.
|
||||
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.
|
||||
Template expressions are similar to JavaScript.
|
||||
Many JavaScript expressions are legal template expressions, with the following exceptions.
|
||||
|
||||
The interpolation braces in `{{1 + 1}}` surround the template expression `1 + 1`.
|
||||
In the property binding,
|
||||
a template expression appears in quotes to the right of the `=` 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:
|
||||
You can't use JavaScript expressions that have or promote side effects, including:
|
||||
|
||||
* Assignments (`=`, `+=`, `-=`, `...`)
|
||||
* Operators such as `new`, `typeof`, `instanceof`, etc.
|
||||
* Operators such as `new`, `typeof`, or `instanceof`
|
||||
* Chaining expressions with <code>;</code> or <code>,</code>
|
||||
* The increment and decrement operators `++` and `--`
|
||||
* 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 `&`
|
||||
* New [template expression operators](guide/template-expression-operators), such as `|`, `?.` and `!`
|
||||
|
||||
|
||||
## Expression context
|
||||
|
||||
The *expression context* is typically the _component_ instance.
|
||||
In the following snippets, the `recommended` within double curly braces and the
|
||||
`itemImageUrl2` in quotes refer to properties of the `AppComponent`.
|
||||
Interpolated expressions have a context—a particular part of the application to which the expression belongs.
|
||||
Typically, this context is the component instance.
|
||||
|
||||
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>
|
||||
|
||||
An expression may also refer to properties of the _template's_ context
|
||||
such as a template input variable,
|
||||
<!-- link to built-in-directives#template-input-variables -->
|
||||
`let customer`, or a template reference variable, `#customerInput`.
|
||||
<!-- link to guide/template-ref-variables -->
|
||||
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).
|
||||
|
||||
The following example uses a template input variable of `customer`.
|
||||
|
||||
<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>
|
||||
|
||||
The context for terms in an expression is a blend of the _template variables_,
|
||||
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,
|
||||
the template variable name takes precedence, followed by a name in the directive's _context_,
|
||||
and, lastly, the component's member names.
|
||||
The context against which an expression evaluates is the union of the template variables, 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:
|
||||
|
||||
1. The template variable name.
|
||||
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`
|
||||
property and the `*ngFor` defines a `customer` template variable.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
The `customer` in `{{customer.name}}`
|
||||
refers to the template input variable, not the component's property.
|
||||
The `customer` in `{{customer.name}}` refers to the template input variable, not the component's property.
|
||||
|
||||
Template expressions cannot refer to anything in
|
||||
the global namespace, except `undefined`. They can't refer to
|
||||
`window` or `document`. Additionally, they
|
||||
can't call `console.log()` or `Math.max()` and they are restricted to referencing
|
||||
members of the expression context.
|
||||
Template expressions cannot refer to anything in the global namespace, except `undefined`.
|
||||
They can't refer to `window` or `document`.
|
||||
Additionally, they can't call `console.log()` or `Math.max()` and they are restricted to referencing members of the expression context.
|
||||
|
||||
</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)
|
||||
* [Quick execution](guide/interpolation#quick-execution)
|
||||
* [No visible side effects](guide/interpolation#no-visible-side-effects)
|
||||
* **Use short expressions**
|
||||
|
||||
### 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
|
||||
practice to avoid them.
|
||||
* **Quick execution**
|
||||
|
||||
A property name or method call should be the norm, but an occasional Boolean negation, `!`, is OK.
|
||||
Otherwise, confine application and business logic to the component,
|
||||
where it is easier to develop and test.
|
||||
Angular executes template expressions after every [change detection](guide/glossary#change-detection) cycle.
|
||||
Many asynchronous activities trigger change detection cycles, such as promise resolutions, HTTP results, timer events, key presses and mouse moves.
|
||||
|
||||
### 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.
|
||||
Change detection cycles are triggered by many asynchronous activities such as
|
||||
promise resolutions, HTTP results, timer events, key presses and mouse moves.
|
||||
* **No visible side effects**
|
||||
|
||||
Expressions should finish quickly or the user experience may drag, especially on slower devices.
|
||||
Consider caching values when their computation is expensive.
|
||||
|
||||
### 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.
|
||||
You should never worry that reading a component value might change some other displayed value.
|
||||
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.
|
||||
Reading a component value should not change some other displayed value.
|
||||
The view should be stable throughout a single rendering pass.
|
||||
|
||||
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.
|
||||
<div class="callout is-important">
|
||||
<header>Idempotent expressions reduce side effects</header>
|
||||
|
||||
An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression 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.
|
||||
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 referential inequality of objects when iterating over them. See [*ngFor with `trackBy`](guide/built-in-directives#ngfor-with-trackby) for details.
|
||||
If an idempotent expression returns a string or a number, it returns the same string or number if you call it twice consecutively.
|
||||
If the expression returns an object, including an `array`, it returns the same object *reference* if you call it twice consecutively.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
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.
|
||||
|
||||
</div>
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
},
|
||||
{
|
||||
"url": "guide/interpolation",
|
||||
"title": "Interpolation",
|
||||
"title": "Text interpolation",
|
||||
"tooltip": "An introduction to interpolation and expressions in HTML."
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue