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;
}
/* #docregion p-span */
p span { color: red; font-size: 70%; }
/* #enddocregion p-span */
.unless {
border: 2px solid;

View File

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

View File

@ -10,8 +10,9 @@ import { Hero, heroes } from './hero';
export class AppComponent {
heroes = heroes;
hero = this.heroes[0];
// #docregion condition
condition = false;
// #enddocregion condition
logs: string[] = [];
showSad = true;
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.
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>
</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>
* [`*ngFor`](guide/structural-directives#inside-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.
* [`*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/built-in-directives#ngIf) is a conditional; it includes the `HeroDetail` component only if a selected hero exists.
#### 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
* 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
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>
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`
@ -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.
{@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
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.
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>`.
@ -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>
<hr />
## 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).

View File

@ -180,7 +180,7 @@ For more information, see [Template reference variables](guide/template-referenc
<live-example name="ngcontainer"></live-example>
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

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 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}
## 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>
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`.

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 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.
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.
<!-- 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
</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.
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>

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.
*
* 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
* 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.
*
* 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,
* put the `*ngIf` on a container element that wraps the `*ngFor` element.
* For futher discussion, see
* [Structural Directives](guide/structural-directives#one-per-element).
* [Structural Directives](guide/built-in-directives#one-per-element).
*
* @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 {
/**
* 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()
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
* 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
* as an attribute of the anchor element for the inserted template.
* 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
* 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
* @publicApi

View File

@ -511,7 +511,7 @@ class ExpressionVisitor extends NullTemplateVisitor {
* These directives allows declaration of "let" variables, adds context-specific
* symbols like $implicit, index, count, among other behaviors.
* 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 binding template binding for the expression in the attribute