docs: rewrite structural-directives.md (#40015)

PR Close #40015
This commit is contained in:
Kapunahele Wong 2020-12-02 12:48:25 -05:00 committed by Zach Arend
parent 356d9a0537
commit 6c783c7fcb
16 changed files with 194 additions and 815 deletions

View File

@ -42,9 +42,7 @@ td, th {
vertical-align: top; vertical-align: top;
} }
/* #docregion p-span */
p span { color: red; font-size: 70%; } p span { color: red; font-size: 70%; }
/* #enddocregion p-span */
.unless { .unless {
border: 2px solid; border: 2px solid;

View File

@ -5,27 +5,21 @@
<p>Conditional display of hero</p> <p>Conditional display of hero</p>
<blockquote> <blockquote>
<!-- #docregion built-in, asterisk, ngif --> <!-- #docregion asterisk -->
<div *ngIf="hero" class="name">{{hero.name}}</div> <div *ngIf="hero" class="name">{{hero.name}}</div>
<!-- #enddocregion built-in, asterisk, ngif --> <!-- #enddocregion asterisk -->
</blockquote> </blockquote>
<p>List of heroes</p> <p>List of heroes</p>
<!-- #docregion built-in -->
<ul> <ul>
<!-- #docregion ngfor-li -->
<li *ngFor="let hero of heroes">{{hero.name}}</li> <li *ngFor="let hero of heroes">{{hero.name}}</li>
<!-- #enddocregion ngfor-li -->
</ul> </ul>
<!-- #enddocregion built-in -->
<hr> <hr>
<h2 id="ngIf">NgIf</h2> <h2 id="ngIf">NgIf</h2>
<!-- #docregion ngif-true -->
<p *ngIf="true"> <p *ngIf="true">
Expression is true and ngIf is true. Expression is true and ngIf is true.
This paragraph is in the DOM. This paragraph is in the DOM.
@ -34,9 +28,7 @@
Expression is false and ngIf is false. Expression is false and ngIf is false.
This paragraph is not in the DOM. This paragraph is not in the DOM.
</p> </p>
<!-- #enddocregion ngif-true -->
<!-- #docregion display-none -->
<p [style.display]="'block'"> <p [style.display]="'block'">
Expression sets display to "block". Expression sets display to "block".
This paragraph is visible. This paragraph is visible.
@ -45,7 +37,6 @@
Expression sets display to "none". Expression sets display to "none".
This paragraph is hidden but still in the DOM. This paragraph is hidden but still in the DOM.
</p> </p>
<!-- #enddocregion display-none -->
<h4>NgIf with template</h4> <h4>NgIf with template</h4>
<p>&lt;ng-template&gt; element</p> <p>&lt;ng-template&gt; element</p>
@ -72,7 +63,7 @@
and continued on my way. and continued on my way.
</p> </p>
<!-- #enddocregion ngif-ngcontainer --> <!-- #enddocregion ngif-ngcontainer -->
<!-- #docregion ngif-span -->
<p> <p>
I turned the corner I turned the corner
<span *ngIf="hero"> <span *ngIf="hero">
@ -80,10 +71,9 @@
</span> </span>
and continued on my way. and continued on my way.
</p> </p>
<!-- #enddocregion ngif-span -->
<p><i>&lt;select&gt; with &lt;span&gt;</i></p> <p><i>&lt;select&gt; with &lt;span&gt;</i></p>
<!-- #docregion select-span -->
<div> <div>
Pick your favorite hero Pick your favorite hero
(<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>) (<label><input type="checkbox" checked (change)="showSad = !showSad">show sad</label>)
@ -95,7 +85,6 @@
</span> </span>
</span> </span>
</select> </select>
<!-- #enddocregion select-span -->
<p><i>&lt;select&gt; with &lt;ng-container&gt;</i></p> <p><i>&lt;select&gt; with &lt;ng-container&gt;</i></p>
<!-- #docregion select-ngcontainer --> <!-- #docregion select-ngcontainer -->
@ -148,17 +137,14 @@
<h4>NgSwitch</h4> <h4>NgSwitch</h4>
<!-- #docregion built-in , ngswitch -->
<div [ngSwitch]="hero?.emotion"> <div [ngSwitch]="hero?.emotion">
<app-happy-hero *ngSwitchCase="'happy'" [hero]="hero"></app-happy-hero> <app-happy-hero *ngSwitchCase="'happy'" [hero]="hero"></app-happy-hero>
<app-sad-hero *ngSwitchCase="'sad'" [hero]="hero"></app-sad-hero> <app-sad-hero *ngSwitchCase="'sad'" [hero]="hero"></app-sad-hero>
<app-confused-hero *ngSwitchCase="'confused'" [hero]="hero"></app-confused-hero> <app-confused-hero *ngSwitchCase="'confused'" [hero]="hero"></app-confused-hero>
<app-unknown-hero *ngSwitchDefault [hero]="hero"></app-unknown-hero> <app-unknown-hero *ngSwitchDefault [hero]="hero"></app-unknown-hero>
</div> </div>
<!-- #enddocregion built-in, ngswitch -->
<h4>NgSwitch with &lt;ng-template&gt;</h4> <h4>NgSwitch with &lt;ng-template&gt;</h4>
<!-- #docregion ngswitch-template -->
<div [ngSwitch]="hero?.emotion"> <div [ngSwitch]="hero?.emotion">
<ng-template [ngSwitchCase]="'happy'"> <ng-template [ngSwitchCase]="'happy'">
<app-happy-hero [hero]="hero"></app-happy-hero> <app-happy-hero [hero]="hero"></app-happy-hero>
@ -173,7 +159,6 @@
<app-unknown-hero [hero]="hero"></app-unknown-hero> <app-unknown-hero [hero]="hero"></app-unknown-hero>
</ng-template> </ng-template>
</div> </div>
<!-- #enddocregion ngswitch-template -->
<hr> <hr>
@ -189,6 +174,7 @@
<hr> <hr>
<h2 id="appUnless">UnlessDirective</h2> <h2 id="appUnless">UnlessDirective</h2>
<!-- #docregion toggle-info -->
<p> <p>
The condition is currently The condition is currently
<span [ngClass]="{ 'a': !condition, 'b': condition, 'unless': true }">{{condition}}</span>. <span [ngClass]="{ 'a': !condition, 'b': condition, 'unless': true }">{{condition}}</span>.
@ -198,6 +184,8 @@
Toggle condition to {{condition ? 'false' : 'true'}} Toggle condition to {{condition ? 'false' : 'true'}}
</button> </button>
</p> </p>
<!-- #enddocregion toggle-info -->
<!-- #docregion appUnless--> <!-- #docregion appUnless-->
<p *appUnless="condition" class="unless a"> <p *appUnless="condition" class="unless a">
(A) This paragraph is displayed because the condition is false. (A) This paragraph is displayed because the condition is false.

View File

@ -10,8 +10,9 @@ import { Hero, heroes } from './hero';
export class AppComponent { export class AppComponent {
heroes = heroes; heroes = heroes;
hero = this.heroes[0]; hero = this.heroes[0];
// #docregion condition
condition = false; condition = false;
// #enddocregion condition
logs: string[] = []; logs: string[] = [];
showSad = true; showSad = true;
status = 'ready'; status = 'ready';

View File

@ -140,7 +140,7 @@ The following table lists some of the key AngularJS template features with their
Angular has true template input variables that are explicitly defined using the `let` keyword. Angular has true template input variables that are explicitly defined using the `let` keyword.
For more information, see the [Template input variables](guide/structural-directives#template-input-variable) section of [Structural Directives](guide/structural-directives). For more information, see the [Structural directive shorthand](guide/structural-directives#shorthand) section of [Structural Directives](guide/structural-directives).
</td> </td>
</tr> </tr>

View File

@ -166,8 +166,8 @@ The example template uses two built-in structural directives to add application
<code-example path="architecture/src/app/hero-list.component.1.html" header="src/app/hero-list.component.html (structural)" region="structural"></code-example> <code-example path="architecture/src/app/hero-list.component.1.html" header="src/app/hero-list.component.html (structural)" region="structural"></code-example>
* [`*ngFor`](guide/structural-directives#inside-ngfor) is an iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list. * [`*ngFor`](guide/built-in-directives#ngFor) is an iterative; it tells Angular to stamp out one `<li>` per hero in the `heroes` list.
* [`*ngIf`](guide/structural-directives#ngif-case-study) is a conditional; it includes the `HeroDetail` component only if a selected hero exists. * [`*ngIf`](guide/built-in-directives#ngIf) is a conditional; it includes the `HeroDetail` component only if a selected hero exists.
#### Attribute directives #### Attribute directives

View File

@ -198,7 +198,7 @@ The string `"let item of items"` instructs Angular to do the following:
* Translate `"let item of items"` into an `<ng-template>` around the host element * Translate `"let item of items"` into an `<ng-template>` around the host element
* Repeat the `<ng-template>` for each `item` in the list * Repeat the `<ng-template>` for each `item` in the list
For more information see the [`<ng-template>` section](guide/structural-directives#the-ng-template) of [Structural directives](guide/structural-directives). For more information see the [Structural directive shorthand](guide/structural-directives#shorthand) section of [Structural directives](guide/structural-directives).
### Repeating a component view ### Repeating a component view
To repeat a component element, apply `*ngFor` to the selector. To repeat a component element, apply `*ngFor` to the selector.
@ -215,7 +215,7 @@ The following example references `item` first in an interpolation and then passe
<code-example path="built-in-directives/src/app/app.component.html" region="NgFor-1-2" header="src/app/app.component.html"></code-example> <code-example path="built-in-directives/src/app/app.component.html" region="NgFor-1-2" header="src/app/app.component.html"></code-example>
For more information about template input variables, see [Structural Directives](guide/structural-directives#template-input-variable). For more information about template input variables, see [Structural directive shorthand](guide/structural-directives#shorthand).
### Getting the `index` of `*ngFor` ### Getting the `index` of `*ngFor`
@ -228,8 +228,12 @@ The following example gets the `index` in a variable named `i` and displays it w
The index property of the `NgFor` directive context returns the zero-based index of the item in each iteration. The index property of the `NgFor` directive context returns the zero-based index of the item in each iteration.
{@a one-per-element} Angular translates this instruction into an `<ng-template>` around the host element,
then uses this template repeatedly to create a new set of elements and bindings for each `item`
in the list.
For more information about shorthand, see the [Structural Directives](guide/structural-directives#shorthand) guide.
{@a one-per-element}
## Repeating elements when a condition is true ## Repeating elements when a condition is true
To repeat a block of HTML when a particular condition is true, put the `*ngIf` on a container element that wraps an `*ngFor` element. To repeat a block of HTML when a particular condition is true, put the `*ngIf` on a container element that wraps an `*ngFor` element.
@ -278,7 +282,7 @@ They do not have special access to any private APIs that other directives can't
The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM. The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.
You can use [`<ng-container>`](guide/structural-directives#ngcontainer) when there's no single element to host the directive. You can use `<ng-container>` when there's no single element to host the directive.
Here's a conditional paragraph using `<ng-container>`. Here's a conditional paragraph using `<ng-container>`.
@ -339,8 +343,6 @@ For example, you could replace the `<app-best-item>` switch case with a `<div>`
<code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch-div" header="src/app/app.component.html"></code-example> <code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch-div" header="src/app/app.component.html"></code-example>
<hr />
## What's next ## What's next
For information on how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives). For information on how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives).

View File

@ -180,7 +180,7 @@ For more information, see [Template reference variables](guide/template-referenc
<live-example name="ngcontainer"></live-example> <live-example name="ngcontainer"></live-example>
Demonstrates `<ngcontainer>`. Demonstrates `<ngcontainer>`.
For more information, see the [ngtemplate section](guide/structural-directives#ngcontainer) of [Structural directives](guide/structural-directives) . For more information, see the [ng-container section](guide/built-in-directives#ngcontainer) of [Built-in directives](guide/structural-directives) .
### Pipes ### Pipes

View File

@ -340,6 +340,12 @@ Angular supplies a number of built-in directives that begin with the `ng` prefix
You can also create new directives to implement your own functionality. You can also create new directives to implement your own functionality.
You associate a *selector* (an HTML tag such as `<my-directive>`) with a custom directive, thereby extending the [template syntax](guide/template-syntax) that you can use in your apps. You associate a *selector* (an HTML tag such as `<my-directive>`) with a custom directive, thereby extending the [template syntax](guide/template-syntax) that you can use in your apps.
**UpperCamelCase**, such as `NgIf`, refers to a directive class.
You can use **UpperCamelCase** when describing properties and directive behavior.
**lowerCamelCase**, such as `ngIf` refers to a directive's attribute name.
You can use **lowerCamelCase** when describing how to apply the directive to an element in the HTML template.
{@a dom} {@a dom}
## domain-specific language (DSL) ## domain-specific language (DSL)

View File

@ -86,7 +86,7 @@ In the following snippet, the expression `recommended` and the expression `itemI
<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 can also refer to properties of the _template's_ context such as a [template input variable](guide/structural-directives#template-input-variables) or a [template reference variable](guide/template-reference-variables). An expression can also refer to properties of the _template's_ context such as a [template input variable](guide/structural-directives#shorthand) or a [template reference variable](guide/template-reference-variables).
The following example uses a template input variable of `customer`. The following example uses a template input variable of `customer`.

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@ Angular assigns a template variable a value based on where you declare the varia
* If you declare the variable on a component, the variable refers to the component instance. * If you declare the variable on a component, the variable refers to the component instance.
* If you declare the variable on a standard HTML tag, the variable refers to the element. * If you declare the variable on a standard HTML tag, the variable refers to the element.
* If you declare the variable on an `<ng-template>` element, the variable refers to a `TemplateRef` instance, which represents the template. * If you declare the variable on an `<ng-template>` element, the variable refers to a `TemplateRef` instance, which represents the template.
For more information on `<ng-template>`, see the [ng-template](guide/structural-directives#the-ng-template) section of [Structural directives](guide/structural-directives). For more information on `<ng-template>`, see [How Angular uses the asterisk, `*`, syntax](guide/structural-directives#asterisk) in [Structural directives](guide/structural-directives).
* If the variable specifies a name on the right-hand side, such as `#var="ngModel"`, the variable refers to the directive or component on the element with a matching `exportAs` name. * If the variable specifies a name on the right-hand side, such as `#var="ngModel"`, the variable refers to the directive or component on the element with a matching `exportAs` name.
<!-- What does the second half of this mean?^^ Can we explain this more fully? Could I see a working example? -kw --> <!-- What does the second half of this mean?^^ Can we explain this more fully? Could I see a working example? -kw -->
@ -152,3 +152,21 @@ name: "TemplateRef"
__proto__: Function __proto__: Function
</code-example> </code-example>
{@a template-input-variable}
{@a template-input-variables}
## Template input variable
A _template input variable_ is a variable you can reference within a single instance of the template.
You declare a template input variable using the `let` keyword as in `let hero`.
There are several such variables in this example: `hero`, `i`, and `odd`.
The variable's scope is limited to a single instance of the repeated template.
You can use the same variable name again in the definition of other structural directives.
In contrast, you declare a template variable by prefixing the variable name with `#`, as in `#var`.
A template variable refers to its attached element, component, or directive.
Template input variables and template variables names have their own namespaces.
The template input variable `hero` in `let hero` is distinct from the template variable `hero` in `#hero`.

View File

@ -50,7 +50,7 @@ For example, `deleteHero()` of `(click)="deleteHero()"` is a method of the compo
The statement context may also refer to properties of the template's own context. The statement context may also refer to properties of the template's own context.
In the following example, the component's event handling method, `onSave()` takes the template's own `$event` object as an argument. In the following example, the component's event handling method, `onSave()` takes the template's own `$event` object as an argument.
On the next two lines, the `deleteHero()` method takes a [template input variable](guide/structural-directives#template-input-variable), `hero`, and `onSubmit()` takes a [template reference variable](guide/template-reference-variables), `#heroForm`. On the next two lines, the `deleteHero()` method takes a [template input variable](guide/structural-directives#shorthand), `hero`, and `onSubmit()` takes a [template reference variable](guide/template-reference-variables), `#heroForm`.
<code-example path="template-syntax/src/app/app.component.html" region="context-var-statement" header="src/app/app.component.html"></code-example> <code-example path="template-syntax/src/app/app.component.html" region="context-var-statement" header="src/app/app.component.html"></code-example>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -38,7 +38,7 @@ export class NgForOfContext<T, U extends NgIterable<T> = NgIterable<T>> {
* of the cloned templates. * of the cloned templates.
* *
* The `ngForOf` directive is generally used in the * The `ngForOf` directive is generally used in the
* [shorthand form](guide/structural-directives#the-asterisk--prefix) `*ngFor`. * [shorthand form](guide/structural-directives#asterisk) `*ngFor`.
* In this form, the template to be rendered for each iteration is the content * In this form, the template to be rendered for each iteration is the content
* of an anchor element containing the directive. * of an anchor element containing the directive.
* *
@ -67,11 +67,11 @@ export class NgForOfContext<T, U extends NgIterable<T> = NgIterable<T>> {
* context according to its lexical position. * context according to its lexical position.
* *
* When using the shorthand syntax, Angular allows only [one structural directive * When using the shorthand syntax, Angular allows only [one structural directive
* on an element](guide/structural-directives#one-structural-directive-per-host-element). * on an element](guide/built-in-directives#one-per-element).
* If you want to iterate conditionally, for example, * If you want to iterate conditionally, for example,
* put the `*ngIf` on a container element that wraps the `*ngFor` element. * put the `*ngIf` on a container element that wraps the `*ngFor` element.
* For futher discussion, see * For futher discussion, see
* [Structural Directives](guide/structural-directives#one-per-element). * [Structural Directives](guide/built-in-directives#one-per-element).
* *
* @usageNotes * @usageNotes
* *
@ -133,7 +133,7 @@ export class NgForOfContext<T, U extends NgIterable<T> = NgIterable<T>> {
export class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCheck { export class NgForOf<T, U extends NgIterable<T> = NgIterable<T>> implements DoCheck {
/** /**
* The value of the iterable expression, which can be used as a * The value of the iterable expression, which can be used as a
* [template input variable](guide/structural-directives#template-input-variable). * [template input variable](guide/structural-directives#shorthand).
*/ */
@Input() @Input()
set ngForOf(ngForOf: U&NgIterable<T>|undefined|null) { set ngForOf(ngForOf: U&NgIterable<T>|undefined|null) {

View File

@ -17,7 +17,7 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, ɵstri
* Angular renders the template provided in an optional `else` clause. The default * Angular renders the template provided in an optional `else` clause. The default
* template for the `else` clause is blank. * template for the `else` clause is blank.
* *
* A [shorthand form](guide/structural-directives#the-asterisk--prefix) of the directive, * A [shorthand form](guide/structural-directives#asterisk) of the directive,
* `*ngIf="condition"`, is generally used, provided * `*ngIf="condition"`, is generally used, provided
* as an attribute of the anchor element for the inserted template. * as an attribute of the anchor element for the inserted template.
* Angular expands this into a more explicit version, in which the anchor element * Angular expands this into a more explicit version, in which the anchor element
@ -143,7 +143,7 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, ɵstri
* *
* The presence of the implicit template object has implications for the nesting of * The presence of the implicit template object has implications for the nesting of
* structural directives. For more on this subject, see * structural directives. For more on this subject, see
* [Structural Directives](https://angular.io/guide/structural-directives#one-per-element). * [Structural Directives](https://angular.io/guide/built-in-directives#one-per-element).
* *
* @ngModule CommonModule * @ngModule CommonModule
* @publicApi * @publicApi

View File

@ -511,7 +511,7 @@ class ExpressionVisitor extends NullTemplateVisitor {
* These directives allows declaration of "let" variables, adds context-specific * These directives allows declaration of "let" variables, adds context-specific
* symbols like $implicit, index, count, among other behaviors. * symbols like $implicit, index, count, among other behaviors.
* For a complete description of such format, see * For a complete description of such format, see
* https://angular.io/guide/structural-directives#the-asterisk--prefix * https://angular.io/guide/structural-directives#asterisk
* *
* @param attr descriptor for attribute name and value pair * @param attr descriptor for attribute name and value pair
* @param binding template binding for the expression in the attribute * @param binding template binding for the expression in the attribute