From 35f7ff047a60cb12df9f7a1e1e92a2b850437973 Mon Sep 17 00:00:00 2001 From: Judy Bogart Date: Fri, 30 Nov 2018 08:29:34 -0800 Subject: [PATCH] docs: add api doc for ngif (#27376) (#28344) PR Close #27376 PR Close #28344 --- packages/common/src/directives/ng_if.ts | 160 +++++++++++++++--------- 1 file changed, 103 insertions(+), 57 deletions(-) diff --git a/packages/common/src/directives/ng_if.ts b/packages/common/src/directives/ng_if.ts index 6597507760..8f72a53e08 100644 --- a/packages/common/src/directives/ng_if.ts +++ b/packages/common/src/directives/ng_if.ts @@ -10,94 +10,140 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, ɵstri /** - * Conditionally includes a template based on the value of an `expression`. + * A structural directive that conditionally includes a template based on the value of + * an expression coerced to Boolean. + * When the expression evaluates to true, Angular renders the template + * provided in a `then` clause, and when false or null, + * Angular renders the template provided in an optional `else` clause. The default + * template for the `else` clause is blank. * - * `ngIf` evaluates the `expression` and then renders the `then` or `else` template in its place - * when expression is truthy or falsy respectively. Typically the: - * - `then` template is the inline template of `ngIf` unless bound to a different value. - * - `else` template is blank unless it is bound. + * A [shorthand form](guide/structural-directives#the-asterisk--prefix) 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 + * is contained in an `` element. * + * Simple form with shorthand syntax: + * + * ``` + *
Content to render when condition is true.
+ * ``` + * + * Simple form with expanded syntax: + * + * ``` + *
Content to render when condition is + * true.
+ * ``` + * + * Form with an "else" block: + * + * ``` + *
Content to render when condition is true.
+ * Content to render when condition is false. + * ``` + * + * Shorthand form with "then" and "else" blocks: + * + * ``` + *
+ * Content to render when condition is true. + * Content to render when condition is false. + * ``` + * + * Form with storing the value locally: + * + * ``` + *
{{value}}
+ * Content to render when value is null. + * ``` * * @usageNotes * - * ### Most common usage + * The `*ngIf` directive is most commonly used to conditionally show an inline template, + * as seen in the following example. + * The default `else` template is blank. * - * The most common usage of the `ngIf` directive is to conditionally show the inline template as - * seen in this example: * {@example common/ngIf/ts/module.ts region='NgIfSimple'} * * ### Showing an alternative template using `else` * - * If it is necessary to display a template when the `expression` is falsy use the `else` template - * binding as shown. Note that the `else` binding points to a `` labeled `#elseBlock`. - * The template can be defined anywhere in the component view but is typically placed right after + * To display a template when `expression` evaluates to false, use an `else` template + * binding as shown in the following example. + * The `else` binding points to an `` element labeled `#elseBlock`. + * The template can be defined anywhere in the component view, but is typically placed right after * `ngIf` for readability. * * {@example common/ngIf/ts/module.ts region='NgIfElse'} * - * ### Using non-inlined `then` template + * ### Using an external `then` template * - * Usually the `then` template is the inlined template of the `ngIf`, but it can be changed using - * a binding (just like `else`). Because `then` and `else` are bindings, the template references can - * change at runtime as shown in this example. + * In the previous example, the then-clause template is specified inline, as the content of the + * tag that contains the `ngIf` directive. You can also specify a template that is defined + * externally, by referencing a labeled `` element. When you do this, you can + * change which template to use at runtime, as shown in the following example. * * {@example common/ngIf/ts/module.ts region='NgIfThenElse'} * - * ### Storing conditional result in a variable + * ### Storing a conditional result in a variable * - * A common pattern is that we need to show a set of properties from the same object. If the - * object is undefined, then we have to use the safe-traversal-operator `?.` to guard against - * dereferencing a `null` value. This is especially the case when waiting on async data such as - * when using the `async` pipe as shown in following example: - * - * ``` - * Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}! - * ``` - * - * There are several inefficiencies in the above example: - * - We create multiple subscriptions on `userStream`. One for each `async` pipe, or two in the - * example above. - * - We cannot display an alternative screen while waiting for the data to arrive asynchronously. - * - We have to use the safe-traversal-operator `?.` to access properties, which is cumbersome. - * - We have to place the `async` pipe in parenthesis. - * - * A better way to do this is to use `ngIf` and store the result of the condition in a local - * variable as shown in the the example below: + * You might want to show a set of properties from the same object. If you are waiting + * for asynchronous data, the object can be undefined. + * In this case, you can use `ngIf` and store the result of the condition in a local + * variable as shown in the the following example. * * {@example common/ngIf/ts/module.ts region='NgIfAs'} * - * Notice that: - * - We use only one `async` pipe and hence only one subscription gets created. - * - `ngIf` stores the result of the `userStream|async` in the local variable `user`. - * - The local `user` can then be bound repeatedly in a more efficient way. - * - No need to use the safe-traversal-operator `?.` to access properties as `ngIf` will only - * display the data if `userStream` returns a value. - * - We can display an alternative template while waiting for the data. + * This code uses only one `AsyncPipe`, so only one subscription is created. + * The conditional statement stores the result of `userStream|async` in the local variable `user`. + * You can then bind the local `user` repeatedly. * - * ### Syntax + * The conditional displays the data only if `userStream` returns a value, + * so you don't need to use the + * [safe-navigation-operator](guide/template-syntax#safe-navigation-operator) (`?.`) + * to guard against null values when accessing properties. + * You can display an alternative template while waiting for the data. * - * Simple form: - * - `
...
` - * - `
...
` + * ### Shorthand syntax + * + * The shorthand syntax `*ngIf` expands into two separate template specifications + * for the "then" and "else" clauses. For example, consider the following shorthand statement, + * that is meant to show a loading page while waiting for data to be loaded. * - * Form with an else block: * ``` - *
...
- * ... + *
+ * ... + *
+ * + * + *
Loading...
+ *
* ``` * - * Form with a `then` and `else` block: + * You can see that the "else" clause references the `` + * with the `#loading` label, and the template for the "then" clause + * is provided as the content of the anchor element. + * + * However, when Angular expands the shorthand syntax, it creates + * another `` tag, with `ngIf` and `ngIfElse` directives. + * The anchor element containing the template for the "then" clause becomes + * the content of this unlabeled `` tag. + * * ``` - *
- * ... - * ... + * + *
+ * ... + *
+ *
+ * + * + *
Loading...
+ *
* ``` * - * Form with storing the value locally: - * ``` - *
{{value}}
- * ... - * ``` + * 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). * * @ngModule CommonModule * @publicApi