You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Angular templates support *control flow blocks* that let you conditionally show, hide, and repeat elements.
3
+
Angular templates support *control flow blocks* that let you conditionally show, hide, and repeat
4
+
elements.
4
5
5
6
<divclass="alert is-important">
6
7
7
-
Angular built-in control flow is in [developer preview](/guide/releases#developer-preview). It is ready to try, but may change before becoming stable.
8
+
Angular built-in control flow is in [developer preview](/guide/releases#developer-preview). It is
9
+
ready to try, but may change before becoming stable.
8
10
9
11
</div>
10
12
@@ -14,11 +16,12 @@ The `@if` block conditionally displays its content when its condition expression
14
16
15
17
```html
16
18
@if (a > b) {
17
-
{{a}} is greater than {{b}}
19
+
{{a}} is greater than {{b}}
18
20
}
19
21
```
20
22
21
-
The `@if` block might have one or more associated `@else` blocks. Immediately after an `@if` block , you can optionally specify any number of `@else if` blocks and one `@else` block:
23
+
The `@if` block might have one or more associated branches. Immediately after an `@if` block,
24
+
you can optionally specify any number of `@else if` blocks and one `@else` block:
22
25
23
26
```html
24
27
@if (a > b) {
@@ -32,7 +35,8 @@ The `@if` block might have one or more associated `@else` blocks. Immediately af
32
35
33
36
### Referencing the conditional expression's result
34
37
35
-
The new built-in `@if` conditional supports referencing of expression results to keep a solution for common coding patterns:
38
+
You can create a reference to the result of an `@if` block's conditional expression and use that
39
+
reference inside the block's content.
36
40
37
41
```html
38
42
@if (users$ | async; as users) {
@@ -42,32 +46,38 @@ The new built-in `@if` conditional supports referencing of expression results to
42
46
43
47
## `@for` block - repeaters
44
48
45
-
The `@for`repeatedly renders content of a block for each item in a collection. The collection can be represented as any JavaScript [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) but there are performance advantages of using a regular `Array`. A basic `@for` loop looks like:
49
+
The `@for`block renders its content for each item in a collection.
but standard JavaScript `Array` values offer performance advantages.
60
+
53
61
### `track` for calculating difference of two collections
54
62
55
-
The value of the `track` expression determines a key used to associate array items with the views in the DOM. Having clear indication of the item identity allows Angular to execute a minimal set of DOM operations as items are added, removed or moved in a collection.
63
+
The `@for` block requires a `track` expression. Angular uses the value of this expression
64
+
as a unique identity for each item. This identity allows the framework to perform the minimal
65
+
set of DOM operations necessary after items are added, removed, or reordered.
56
66
57
-
Loops over immutable data without `trackBy` as one of the most common causes for performance issues across Angular applications. Because of the potential for poor performance, the `track` expression is required for the `@for` loops. When in doubt, using `track $index`is a good default.
67
+
For simple cases, you can use `track $index`as a reasonable default.
58
68
59
69
### `$index` and other contextual variables
60
70
61
-
Inside `@for`contents, several implicit variables are always available:
71
+
Inside `@for` contents, several implicit variables are always available:
|`$count`| Number of items in a collection iterated over |
66
-
|`$index`| Index of the current row |
67
-
|`$first`| Whether the current row is the first row |
68
-
|`$last`| Whether the current row is the last row |
69
-
|`$even`| Whether the current row index is even |
70
-
|`$odd`| Whether the current row index is odd |
76
+
|`$index`| Index of the current row |
77
+
|`$first`| Whether the current row is the first row |
78
+
|`$last`| Whether the current row is the last row|
79
+
|`$even`| Whether the current row index is even|
80
+
|`$odd`| Whether the current row index is odd|
71
81
72
82
These variables are always available with these names, but can be aliased via a `let` segment:
73
83
@@ -77,23 +87,25 @@ These variables are always available with these names, but can be aliased via a
77
87
}
78
88
```
79
89
80
-
The aliasing is especially useful in case of using nested `@for` blocks where contextual variable names could collide.
90
+
Aliasing is useful when nesting `@for` blocks so that you can reference these variable values in
91
+
deeper blocks.
81
92
82
93
### `empty` block
83
94
84
-
You can optionally include an `@empty` section immediately after the `@for` block content. The content of the `@empty` block displays when there are no items:
95
+
You can optionally include an `@empty` section immediately after the `@for` block content. The
96
+
content of the `@empty` block displays when there are no items:
85
97
86
98
```html
87
99
@for (item of items; track item.name) {
88
-
<li> {{ item.name }}</li>
100
+
<li> {{ item.name }}</li>
89
101
} @empty {
90
-
<li> There are no items.</li>
102
+
<li> There are no items.</li>
91
103
}
92
104
```
93
105
94
106
## `@switch` block - selection
95
107
96
-
The syntax for `switch` is very similar to `if`, and is inspired by the JavaScript `switch` statement:
108
+
The syntax for `switch` is similar to `if`, inspired by the JavaScript `switch` statement:
97
109
98
110
```html
99
111
@switch (condition) {
@@ -109,29 +121,45 @@ The syntax for `switch` is very similar to `if`, and is inspired by the JavaScri
109
121
}
110
122
```
111
123
112
-
The value of the conditional expression is compared to the case expression using the `===` operator.
124
+
The value of the conditional expression is compared to the case expression using the `===` operator.
113
125
114
-
**`@switch` does not have fallthrough**, so you do not need an equivalent to a `break` or `return` statement.
126
+
**`@switch` does not have fallthrough**, so you do not need an equivalent to a `break` or `return`
127
+
statement.
115
128
116
-
The `@default` block is optional and can be omitted. If no `@case` matches the expression and there is no `@default` block, nothing is shown.
129
+
The `@default` block is optional and can be omitted. If no `@case` matches the expression and there
130
+
is no `@default` block, nothing is shown.
117
131
118
-
## Built-in control flow and the `NgIf`, `NgSwitch` and `NgFor` structural directives
132
+
## Comparing built-in control flow to `NgIf`, `NgSwitch` and `NgFor`
119
133
120
134
The `@if` block replaces `*ngIf` for expressing conditional parts of the UI.
121
135
122
136
The `@switch` block replaces `ngSwitch` with major benefits:
123
-
* it does not require a container element to hold the condition expression or each conditional template;
124
-
* it supports template type-checking, including type narrowing within each branch.
125
137
126
-
The `@for` block replaces `*ngFor` for iteration, and has several differences compared to its structural directive `NgFor` predecessor:
127
-
* tracking expression (calculating keys corresponding to object identities) is mandatory but has better ergonomic (it is enough to write an expression instead of creating the `trackBy` method);
128
-
* uses a new optimized algorithm for calculating a minimal number of DOM operations to be performed in response to changes in a collection, instead of Angular’s customizable diffing implementation (`IterableDiffer`);
129
-
* has support for `@empty` blocks.
138
+
* The `@switch` block does not require a container element for the condition expression or each
139
+
conditional template.
140
+
* The `@switch` block supports template type-checking, including type narrowing within each branch.
141
+
142
+
The `@for` block replaces `*ngFor` for iteration, and has several differences compared to its
143
+
structural directive `NgFor` predecessor:
130
144
131
-
The `track` setting replaces `NgFor`'s concept of a `trackBy` function. Because `@for` is built-in, we can provide a better experience than passing a `trackBy` function, and directly use an expression representing the key instead. Migrating from `trackBy` to `track` is possible by invoking the `trackBy` function:
145
+
* The `@for` block requires a tracking expression to uniquely identify items in the collection.
146
+
While `NgFor` requires a `trackBy`_method_, however, the `@for` block simplifies tracking by
147
+
accepting a `track`_expression_.
148
+
* You can specify content to show when the collection is empty with the `@empty` block.
149
+
* The `@for` block uses an optimized algorithm for determining a minimal number of DOM operations
150
+
necessary after a collection is modified. While `NgFor` allowed developers to provide a custom
151
+
`IterableDiffer` implementation, the `@for` block does not support custom differs.
152
+
153
+
The `track` setting replaces `NgFor`'s concept of a `trackBy` function. Because `@for` is built-in,
154
+
we can provide a better experience than passing a `trackBy` function, and directly use an expression
155
+
representing the key instead. Migrating from `trackBy` to `track` is possible by invoking
156
+
the `trackBy` function:
132
157
133
158
```html
134
159
@for (item of items; track itemId($index, item)) {
135
160
{{ item.name }}
136
161
}
137
162
```
163
+
164
+
With `NgFor`, loops over immutable data without `trackBy` are the most common cause of performance
0 commit comments