PR #36601 introduces icons on all links if the link contains https:// or http:// but there were some internal links left which contained https://angular.io. Removed https://angular.io from all these links. PR Close #38360
		
			
				
	
	
		
			436 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			436 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Built-in directives
 | |
| 
 | |
| Angular offers two kinds of built-in directives: [_attribute_ directives](guide/attribute-directives) and [_structural_ directives](guide/structural-directives).
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| See the <live-example></live-example> for a working example containing the code snippets in this guide.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| For more detail, including how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives).
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a attribute-directives}
 | |
| 
 | |
| ## Built-in attribute directives
 | |
| 
 | |
| Attribute directives listen to and modify the behavior of
 | |
| other HTML elements, attributes, properties, and components.
 | |
| You usually apply them to elements as if they were HTML attributes, hence the name.
 | |
| 
 | |
| Many NgModules such as the [`RouterModule`](guide/router "Routing and Navigation")
 | |
| and the [`FormsModule`](guide/forms "Forms") define their own attribute directives.
 | |
| The most common attribute directives are as follows:
 | |
| 
 | |
| * [`NgClass`](guide/built-in-directives#ngClass)—adds and removes a set of CSS classes.
 | |
| * [`NgStyle`](guide/built-in-directives#ngStyle)—adds and removes a set of HTML styles.
 | |
| * [`NgModel`](guide/built-in-directives#ngModel)—adds two-way data binding to an HTML form element.
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a ngClass}
 | |
| 
 | |
| ## `NgClass`
 | |
| 
 | |
| Add or remove several CSS classes simultaneously with `ngClass`.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="special-div" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| To add or remove a *single* class, use [class binding](guide/attribute-binding#class-binding) rather than `NgClass`.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| Consider a `setCurrentClasses()` component method that sets a component property,
 | |
| `currentClasses`, with an object that adds or removes three classes based on the
 | |
| `true`/`false` state of three other component properties. Each key of the object is a CSS class name; its value is `true` if the class should be added,
 | |
| `false` if it should be removed.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.ts" region="setClasses" header="src/app/app.component.ts"></code-example>
 | |
| 
 | |
| Adding an `ngClass` property binding to `currentClasses` sets the element's classes accordingly:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgClass-1" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| Remember that in this situation you'd call `setCurrentClasses()`,
 | |
| both initially and when the dependent properties change.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a ngStyle}
 | |
| 
 | |
| ## `NgStyle`
 | |
| 
 | |
| Use `NgStyle` to set many inline styles simultaneously and dynamically, based on the state of the component.
 | |
| 
 | |
| ### Without `NgStyle`
 | |
| 
 | |
| For context, consider setting a *single* style value with [style binding](guide/attribute-binding#style-binding), without `NgStyle`.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="without-ng-style" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| However, to set *many* inline styles at the same time, use the `NgStyle` directive.
 | |
| 
 | |
| The following is a `setCurrentStyles()` method that sets a component
 | |
| property, `currentStyles`, with an object that defines three styles,
 | |
| based on the state of three other component properties:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.ts" region="setStyles" header="src/app/app.component.ts"></code-example>
 | |
| 
 | |
| Adding an `ngStyle` property binding to `currentStyles` sets the element's styles accordingly:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgStyle-2" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| Remember to call `setCurrentStyles()`, both initially and when the dependent properties change.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a ngModel}
 | |
| 
 | |
| ## `[(ngModel)]`: Two-way binding
 | |
| 
 | |
| The `NgModel` directive allows you to display a data property and
 | |
| update that property when the user makes changes. Here's an example:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" header="src/app/app.component.html (NgModel example)" region="NgModel-1"></code-example>
 | |
| 
 | |
| 
 | |
| ### Import `FormsModule` to use `ngModel`
 | |
| 
 | |
| Before using the `ngModel` directive in a two-way data binding,
 | |
| you must import the `FormsModule` and add it to the NgModule's `imports` list.
 | |
| Learn more about the `FormsModule` and `ngModel` in [Forms](guide/forms#ngModel).
 | |
| 
 | |
| Remember to import the `FormsModule` to make `[(ngModel)]` available as follows:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.module.ts" header="src/app/app.module.ts (FormsModule import)" region="import-forms-module"></code-example>
 | |
| 
 | |
| 
 | |
| You could achieve the same result with separate bindings to
 | |
| the `<input>` element's  `value` property and `input` event:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="without-NgModel" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| To streamline the syntax, the `ngModel` directive hides the details behind its own `ngModel` input and `ngModelChange` output properties:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgModelChange" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| The `ngModel` data property sets the element's value property and the `ngModelChange` event property
 | |
| listens for changes to the element's value.
 | |
| 
 | |
| ### `NgModel` and value accessors
 | |
| 
 | |
| The details are specific to each kind of element and therefore the `NgModel` directive only works for an element
 | |
| supported by a [ControlValueAccessor](api/forms/ControlValueAccessor)
 | |
| that adapts an element to this protocol.
 | |
| Angular provides *value accessors* for all of the basic HTML form elements and the
 | |
| [Forms](guide/forms) guide shows how to bind to them.
 | |
| 
 | |
| You can't apply `[(ngModel)]` to a non-form native element or a
 | |
| third-party custom component until you write a suitable value accessor. For more information, see
 | |
| the API documentation on [DefaultValueAccessor](api/forms/DefaultValueAccessor).
 | |
| 
 | |
| You don't need a value accessor for an Angular component that
 | |
| you write because you can name the value and event properties
 | |
| to suit Angular's basic [two-way binding syntax](guide/two-way-binding)
 | |
| and skip `NgModel` altogether.
 | |
| The `sizer` in the
 | |
| [Two-way Binding](guide/two-way-binding) section is an example of this technique.
 | |
| 
 | |
| Separate `ngModel` bindings are an improvement over binding to the
 | |
| element's native properties, but you can streamline the binding with a
 | |
| single declaration using the `[(ngModel)]` syntax:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgModel-1" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| This `[(ngModel)]` syntax can only _set_ a data-bound property.
 | |
| If you need to do something more, you can write the expanded form;
 | |
| for example, the following changes the `<input>` value to uppercase:
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="uppercase" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| Here are all variations in action, including the uppercase version:
 | |
| 
 | |
| <div class="lightbox">
 | |
|   <img src='generated/images/guide/built-in-directives/ng-model-anim.gif' alt="NgModel variations">
 | |
| </div>
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a structural-directives}
 | |
| 
 | |
| ## Built-in _structural_ directives
 | |
| 
 | |
| Structural directives are responsible for HTML layout.
 | |
| They shape or reshape the DOM's structure, typically by adding, removing, and manipulating
 | |
| the host elements to which they are attached.
 | |
| 
 | |
| This section is an introduction to the common built-in structural directives:
 | |
| 
 | |
| * [`NgIf`](guide/built-in-directives#ngIf)—conditionally creates or destroys subviews from the template.
 | |
| * [`NgFor`](guide/built-in-directives#ngFor)—repeat a node for each item in a list.
 | |
| * [`NgSwitch`](guide/built-in-directives#ngSwitch)—a set of directives that switch among alternative views.
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| The deep details of structural directives are covered in the
 | |
| [Structural Directives](guide/structural-directives) guide,
 | |
| which explains the following:
 | |
| 
 | |
| * Why you
 | |
| [prefix the directive name with an asterisk (\*)](guide/structural-directives#the-asterisk--prefix).
 | |
| * Using [`<ng-container>`](guide/structural-directives#ngcontainer "<ng-container>")
 | |
| to group elements when there is no suitable host element for the directive.
 | |
| * How to write your own structural directive.
 | |
| * That you can only apply [one structural directive](guide/structural-directives#one-per-element "one per host element") to an element.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a ngIf}
 | |
| 
 | |
| ## NgIf
 | |
| 
 | |
| You can add or remove an element from the DOM by applying an `NgIf` directive to
 | |
| a host element.
 | |
| Bind the directive to a condition expression like `isActive` in this example.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgIf-1" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| Don't forget the asterisk (`*`) in front of `ngIf`. For more information
 | |
| on the asterisk, see the [asterisk (*) prefix](guide/structural-directives#the-asterisk--prefix) section of
 | |
| [Structural Directives](guide/structural-directives).
 | |
| 
 | |
| </div>
 | |
| 
 | |
| When the `isActive` expression returns a truthy value, `NgIf` adds the
 | |
| `ItemDetailComponent` to the DOM.
 | |
| When the expression is falsy, `NgIf` removes the `ItemDetailComponent`
 | |
| from the DOM, destroying that component and all of its sub-components.
 | |
| 
 | |
| 
 | |
| ### Show/hide vs. `NgIf`
 | |
| 
 | |
| Hiding an element is different from removing it with `NgIf`.
 | |
| For comparison, the following example shows how to control
 | |
| the visibility of an element with a
 | |
| [class](guide/attribute-binding#class-binding) or [style](guide/attribute-binding#style-binding) binding.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgIf-3" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| When you hide an element, that element and all of its descendants remain in the DOM.
 | |
| All components for those elements stay in memory and
 | |
| Angular may continue to check for changes.
 | |
| You could be holding onto considerable computing resources and degrading performance
 | |
| unnecessarily.
 | |
| 
 | |
| `NgIf` works differently. When `NgIf` is `false`, Angular removes the element and its descendants from the DOM.
 | |
| It destroys their components, freeing up resources, which
 | |
| results in a better user experience.
 | |
| 
 | |
| If you are hiding large component trees, consider `NgIf` as a more
 | |
| efficient alternative to showing/hiding.
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| For more information on `NgIf` and `ngIfElse`, see the [API documentation about NgIf](api/common/NgIf).
 | |
| 
 | |
| </div>
 | |
| 
 | |
| ### Guard against null
 | |
| 
 | |
| Another advantage of `ngIf` is that you can use it to guard against null. Show/hide
 | |
| is best suited for very simple use cases, so when you need a guard, opt instead for `ngIf`. Angular will throw an error if a nested expression tries to access a property of `null`.
 | |
| 
 | |
| The following shows `NgIf` guarding two `<div>`s.
 | |
| The `currentCustomer` name appears only when there is a `currentCustomer`.
 | |
| The `nullCustomer` will not be displayed as long as it is `null`.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2b" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| See also the
 | |
| [safe navigation operator](guide/template-expression-operators#safe-navigation-operator "Safe navigation operator (?.)") below.
 | |
| 
 | |
| </div>
 | |
| <hr/>
 | |
| 
 | |
| {@a ngFor}
 | |
| ## `NgFor`
 | |
| 
 | |
| `NgFor` is a repeater directive—a way to present a list of items.
 | |
| You define a block of HTML that defines how a single item should be displayed
 | |
| and then you tell Angular to use that block as a template for rendering each item in the list.
 | |
| The text assigned to `*ngFor` is the instruction that guides the repeater process.
 | |
| 
 | |
| The following example shows `NgFor` applied to a simple `<div>`. (Don't forget the asterisk (`*`) in front of `ngFor`.)
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgFor-1" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| Don't forget the asterisk (`*`) in front of `ngFor`. For more information
 | |
| on the asterisk, see the [asterisk (*) prefix](guide/structural-directives#the-asterisk--prefix) section of
 | |
| [Structural Directives](guide/structural-directives).
 | |
| 
 | |
| </div>
 | |
| 
 | |
| You can also apply an `NgFor` to a component element, as in the following example.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgFor-2" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| {@a microsyntax}
 | |
| 
 | |
| <div class="callout is-critical">
 | |
| <header>*ngFor microsyntax</header>
 | |
| 
 | |
| The string assigned to `*ngFor` is not a [template expression](guide/interpolation). Rather,
 | |
| it's a *microsyntax*—a little language of its own that Angular interprets.
 | |
| The string `"let item of items"` means:
 | |
| 
 | |
| > *Take each item in the `items` array, store it in the local `item` looping variable, and
 | |
| make it available to the templated HTML for each iteration.*
 | |
| 
 | |
| 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 microsyntax, see the [Structural Directives](guide/structural-directives#microsyntax) guide.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| 
 | |
| {@a template-input-variable}
 | |
| 
 | |
| {@a template-input-variables}
 | |
| 
 | |
| ### Template input variables
 | |
| 
 | |
| The `let` keyword before `item` creates a template input variable called `item`.
 | |
| The `ngFor` directive iterates over the `items` array returned by the parent component's `items` property
 | |
| and sets `item` to the current item from the array during each iteration.
 | |
| 
 | |
| Reference `item` within the `ngFor` host element
 | |
| as well as within its descendants to access the item's properties.
 | |
| The following example references `item` first in an interpolation
 | |
| and then passes in a binding to the `item` property of the `<app-item-detail>` component.
 | |
| 
 | |
| <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).
 | |
| 
 | |
| ### `*ngFor` with `index`
 | |
| 
 | |
| The `index` property of the `NgFor` directive context
 | |
| returns the zero-based index of the item in each iteration.
 | |
| You can capture the `index` in a template input variable and use it in the template.
 | |
| 
 | |
| The next example captures the `index` in a variable named `i` and displays it with the item name.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgFor-3" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| `NgFor` is implemented by the `NgForOf` directive. Read more about the other `NgForOf` context values such as `last`, `even`,
 | |
| and `odd` in the [NgForOf API reference](api/common/NgForOf).
 | |
| 
 | |
| </div>
 | |
| 
 | |
| {@a trackBy}
 | |
| ### *ngFor with `trackBy`
 | |
| 
 | |
| If you use `NgFor` with large lists, a small change to one item, such as removing or adding an item, can trigger a cascade of DOM manipulations. For example, re-querying the server could reset a list with all new item objects, even when those items were previously displayed. In this case, Angular sees only a fresh list of new object references and has no choice but to replace the old DOM elements with all new DOM elements.
 | |
| 
 | |
| You can make this more efficient with `trackBy`.
 | |
| Add a method to the component that returns the value `NgFor` should track.
 | |
| In this case, that value is the hero's `id`. If the `id` has already been rendered,
 | |
| Angular keeps track of it and doesn't re-query the server for the same `id`.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.ts" region="trackByItems" header="src/app/app.component.ts"></code-example>
 | |
| 
 | |
| In the microsyntax expression, set `trackBy` to the `trackByItems()` method.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="trackBy" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| Here is an illustration of the `trackBy` effect.
 | |
| "Reset items" creates new items with the same `item.id`s.
 | |
| "Change ids" creates new items with new `item.id`s.
 | |
| 
 | |
| * With no `trackBy`, both buttons trigger complete DOM element replacement.
 | |
| * With `trackBy`, only changing the `id` triggers element replacement.
 | |
| 
 | |
| <div class="lightbox">
 | |
|   <img src="generated/images/guide/built-in-directives/ngfor-trackby.gif" alt="Animation of trackBy">
 | |
| </div>
 | |
| 
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
| Built-in directives use only public APIs; that is,
 | |
| they do not have special access to any private APIs that other directives can't access.
 | |
| 
 | |
| </div>
 | |
| 
 | |
| <hr/>
 | |
| 
 | |
| {@a ngSwitch}
 | |
| ## The `NgSwitch` directives
 | |
| 
 | |
| NgSwitch is like the JavaScript `switch` statement.
 | |
| It displays one element from among several possible elements, based on a switch condition.
 | |
| Angular puts only the selected element into the DOM.
 | |
| <!-- API Flagged -->
 | |
| `NgSwitch` is actually a set of three, cooperating directives:
 | |
| `NgSwitch`, `NgSwitchCase`, and `NgSwitchDefault` as in the following example.
 | |
| 
 | |
|  <code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| <div class="lightbox">
 | |
|   <img src="generated/images/guide/built-in-directives/ngswitch.gif" alt="Animation of NgSwitch">
 | |
| </div>
 | |
| 
 | |
| `NgSwitch` is the controller directive. Bind it to an expression that returns
 | |
| the *switch value*, such as `feature`. Though the `feature` value in this
 | |
| example is a string, the switch value can be of any type.
 | |
| 
 | |
| **Bind to `[ngSwitch]`**. You'll get an error if you try to set `*ngSwitch` because
 | |
| `NgSwitch` is an *attribute* directive, not a *structural* directive.
 | |
| Rather than touching the DOM directly, it changes the behavior of its companion directives.
 | |
| 
 | |
| **Bind to `*ngSwitchCase` and `*ngSwitchDefault`**.
 | |
| The `NgSwitchCase` and `NgSwitchDefault` directives are _structural_ directives
 | |
| because they add or remove elements from the DOM.
 | |
| 
 | |
| * `NgSwitchCase` adds its element to the DOM when its bound value equals the switch value and removes
 | |
| its bound value when it doesn't equal the switch value.
 | |
| 
 | |
| * `NgSwitchDefault` adds its element to the DOM when there is no selected `NgSwitchCase`.
 | |
| 
 | |
| The switch directives are particularly useful for adding and removing *component elements*.
 | |
| This example switches among four `item` components defined in the `item-switch.components.ts` file.
 | |
| Each component has an `item` [input property](guide/inputs-outputs#input "Input property")
 | |
| which is bound to the `currentItem` of the parent component.
 | |
| 
 | |
| Switch directives work as well with native elements and web components too.
 | |
| For example, you could replace the `<app-best-item>` switch case with the following.
 | |
| 
 | |
| <code-example path="built-in-directives/src/app/app.component.html" region="NgSwitch-div" header="src/app/app.component.html"></code-example>
 |