| 
									
										
										
										
											2017-05-26 21:28:06 +02:00
										 |  |  | # Structural Directives
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | <style> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |   h4 {font-size: 17px !important; text-transform: none !important;} | 
					
						
							|  |  |  |   .syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </style> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | This guide looks at how Angular manipulates the DOM with **structural directives** and | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | how you can write your own structural directives to do the same thing. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Try the <live-example></live-example>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a definition} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## What are structural directives?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Structural directives are responsible for HTML layout. | 
					
						
							|  |  |  | They shape or reshape the DOM's _structure_, typically by adding, removing, or manipulating | 
					
						
							|  |  |  | elements. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | As with other directives, you apply a structural directive to a _host element_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The directive then does whatever it's supposed to do with that host element and its descendents. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Structural directives are easy to recognize. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | An asterisk (*) precedes the directive attribute name as in this example. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif)" region="ngif"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | No brackets. No parentheses. Just `*ngIf` set to a string. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | You'll learn in this guide that the [asterisk (*) is a convenience notation](guide/structural-directives#asterisk) | 
					
						
							|  |  |  | and the string is a [_microsyntax_](guide/structural-directives#microsyntax) rather than the usual | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | [template expression](guide/template-syntax#template-expressions). | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | Angular desugars this notation into a marked-up `<ng-template>` that surrounds the | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | host element and its descendents. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Each structural directive does something different with that template. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Three of the common, built-in structural directives—[NgIf](guide/template-syntax#ngIf), | 
					
						
							|  |  |  | [NgFor](guide/template-syntax#ngFor), and [NgSwitch...](guide/template-syntax#ngSwitch)—are | 
					
						
							|  |  |  | described in the [_Template Syntax_](guide/template-syntax) guide and seen in samples throughout the Angular documentation. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Here's an example of them in a template: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (built-in)" region="built-in"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | This guide won't repeat how to _use_ them. But it does explain _how they work_ | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | and how to [write your own](guide/structural-directives#unless) structural directive. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="callout is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | <header> | 
					
						
							|  |  |  |   Directive spelling | 
					
						
							|  |  |  | </header> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Throughout this guide, you'll see a directive spelled in both _UpperCamelCase_ and _lowerCamelCase_. | 
					
						
							|  |  |  | Already you've seen `NgIf` and `ngIf`. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | There's a reason. `NgIf` refers to the directive _class_; | 
					
						
							|  |  |  | `ngIf` refers to the directive's _attribute name_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | A directive _class_ is spelled in _UpperCamelCase_ (`NgIf`). | 
					
						
							|  |  |  | A directive's _attribute name_ is spelled in _lowerCamelCase_ (`ngIf`). | 
					
						
							|  |  |  | The guide refers to the directive _class_ when talking about its properties and what the directive does. | 
					
						
							|  |  |  | The guide refers to the _attribute name_ when describing how | 
					
						
							|  |  |  | you apply the directive to an element in the HTML template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | There are two other kinds of Angular directives, described extensively elsewhere: | 
					
						
							|  |  |  | (1) components and (2) attribute directives. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | A *component* manages a region of HTML in the manner of a native HTML element. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Technically it's a directive with a template. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | An [*attribute* directive](guide/attribute-directives) changes the appearance or behavior | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | of an element, component, or another directive. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | For example, the built-in [`NgStyle`](guide/template-syntax#ngStyle) directive | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | changes several element styles at the same time. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can apply many _attribute_ directives to one host element. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | You can [only apply one](guide/structural-directives#one-per-element) _structural_ directive to a host element. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | {@a ngIf} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | ## NgIf case study
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | `NgIf` is the simplest structural directive and the easiest to understand. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | It takes a boolean expression and makes an entire chunk of the DOM appear or disappear. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-true)" region="ngif-true"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `ngIf` directive doesn't hide elements with CSS. It adds and removes them physically from the DOM. | 
					
						
							|  |  |  | Confirm that fact using browser developer tools to inspect the DOM. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/element-not-in-dom.png' alt="ngIf=false element not in DOM"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | The top paragraph is in the DOM. The bottom, disused paragraph is not; | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | in its place is a comment about "bindings" (more about that [later](guide/structural-directives#asterisk)). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | When the condition is false, `NgIf` removes its host element from the DOM, | 
					
						
							|  |  |  | detaches it from DOM events (the attachments that it made), | 
					
						
							|  |  |  | detaches the component from Angular change detection, and destroys it. | 
					
						
							|  |  |  | The component and DOM nodes can be garbage-collected and free up memory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Why *remove* rather than *hide*?
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A directive could hide the unwanted paragraph instead by setting its `display` style to `none`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (display-none)" region="display-none"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | While invisible, the element remains in the DOM. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/element-display-in-dom.png' alt="hidden element still in DOM"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | The difference between hiding and removing doesn't matter for a simple paragraph. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | It does matter when the host element is attached to a resource intensive component. | 
					
						
							|  |  |  | Such a component's behavior continues even when hidden. | 
					
						
							|  |  |  | The component stays attached to its DOM element. It keeps listening to events. | 
					
						
							|  |  |  | Angular keeps checking for changes that could affect data bindings. | 
					
						
							|  |  |  | Whatever the component was doing, it keeps doing. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Although invisible, the component—and all of its descendant components—tie up resources. | 
					
						
							|  |  |  | The performance and memory burden can be substantial, responsiveness can degrade, and the user sees nothing. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | On the positive side, showing the element again is quick. | 
					
						
							|  |  |  | The component's previous state is preserved and ready to display. | 
					
						
							|  |  |  | The component doesn't re-initialize—an operation that could be expensive. | 
					
						
							|  |  |  | So hiding and showing is sometimes the right thing to do. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | But in the absence of a compelling reason to keep them around, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | your preference should be to remove DOM elements that the user can't see | 
					
						
							|  |  |  | and recover the unused resources with a structural directive like `NgIf` . | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **These same considerations apply to every structural directive, whether built-in or custom.** | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Before applying a structural directive, you might want to pause for a moment | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | to consider the consequences of adding and removing elements and of creating and destroying components. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a asterisk} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | ## The asterisk (*) prefix
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Surely you noticed the asterisk (*) prefix to the directive name | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and wondered why it is necessary and what it does. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here is `*ngIf` displaying the hero's name if `hero` exists. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (asterisk)" region="asterisk"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The asterisk is "syntactic sugar" for something a bit more complicated. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Internally, Angular desugars it in two stages. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | First, it translates the `*ngIf="..."` into a template _attribute_, `template="ngIf ..."`,  like this. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-template-attr)" region="ngif-template-attr"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | Then it translates the template _attribute_ into a `<ng-template>` _element_, wrapped around the host element, like this. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-template)" region="ngif-template"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | * The `*ngIf` directive moved to the `<ng-template>` element where it became a property binding,`[ngIf]`. | 
					
						
							|  |  |  | * The rest of the `<div>`, including its class attribute, moved inside the `<ng-template>` element. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | None of these forms are actually rendered. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Only the finished product ends up in the DOM. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/hero-div-in-dom.png' alt="hero div in DOM"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Angular consumed the `<ng-template>` content during its actual rendering and | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | replaced the `<ng-template>` with a diagnostic comment. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | The [`NgFor`](guide/structural-directives#ngFor) and [`NgSwitch...`](guide/structural-directives#ngSwitch) directives follow the same pattern. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | {@a ngFor} | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Inside _*ngFor_
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Angular transforms the `*ngFor` in similar fashion from asterisk (*) syntax through | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | template _attribute_ to `<ng-template>` _element_. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Here's a full-featured application of `NgFor`, written all three ways: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (inside-ngfor)" region="inside-ngfor"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | This is manifestly more complicated than `ngIf` and rightly so. | 
					
						
							|  |  |  | The `NgFor` directive has more features, both required and optional, than the `NgIf` shown in this guide. | 
					
						
							|  |  |  | At minimum `NgFor` needs a looping variable (`let hero`) and a list (`heroes`). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | You enable these features in the string assigned to `ngFor`, which you write in Angular's [microsyntax](guide/structural-directives#microsyntax). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="alert is-helpful"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Everything _outside_ the `ngFor` string stays with the host element | 
					
						
							|  |  |  | (the `<div>`) as it moves inside the `<ng-template>`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | In this example, the `[ngClass]="odd"` stays on the `<div>`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a microsyntax} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | ### Microsyntax
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The Angular microsyntax lets you configure a directive in a compact, friendly string. | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | The microsyntax parser translates that string into attributes on the `<ng-template>`: | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | * The `let` keyword declares a [_template input variable_](guide/structural-directives#template-input-variable) | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that you reference within the template. The input variables in this example are `hero`, `i`, and `odd`. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | The parser translates `let hero`, `let i`, and `let odd` into variables named, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | `let-hero`, `let-i`, and `let-odd`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | * The microsyntax parser takes `of` and `trackby`, title-cases them (`of` -> `Of`, `trackBy` -> `TrackBy`), | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and prefixes them with the directive's attribute name (`ngFor`), yielding the names `ngForOf` and `ngForTrackBy`. | 
					
						
							|  |  |  | Those are the names of two `NgFor` _input properties_ . | 
					
						
							|  |  |  | That's how the directive learns that the list is `heroes` and the track-by function is `trackById`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * As the `NgFor` directive loops through the list, it sets and resets properties of its own _context_ object. | 
					
						
							|  |  |  | These properties include `index` and `odd` and a special property named `$implicit`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * The `let-i` and `let-odd` variables were defined as `let i=index` and `let odd=odd`. | 
					
						
							|  |  |  | Angular sets them to the current value of the context's `index` and `odd` properties. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | * The context property for `let-hero` wasn't specified. | 
					
						
							|  |  |  | It's intended source is implicit. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Angular sets `let-hero` to the value of the context's `$implicit` property | 
					
						
							|  |  |  | which `NgFor` has initialized with the hero for the current iteration. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | * The [API guide](api/common/NgFor "API: NgFor") | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | describes additional `NgFor` directive properties and context properties. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | These microsyntax mechanisms are available to you when you write your own structural directives. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Studying the | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | [source code for `NgIf`](https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_if.ts "Source: NgIf") | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | and [`NgFor`](https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_for_of.ts "Source: NgFor") | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | is a great way to learn more. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a template-input-variable} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a template-input-variables} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### Template input variable
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A _template input variable_ is a variable whose value you can reference _within_ a single instance of the template. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | There are several such variables in this example: `hero`, `i`, and `odd`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | All are preceded by the keyword `let`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | A _template input variable_ is **_not_** the same as a | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | [template _reference_ variable](guide/template-syntax#ref-vars), | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | neither _semantically_ nor _syntactically_. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | You declare a template _input_ variable using the `let` keyword (`let hero`). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | You declare a template _reference_ variable by prefixing the variable name with `#` (`#var`). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | A _reference_ variable refers to its attached element, component or directive. | 
					
						
							|  |  |  | It can be accessed _anywhere_ in the _entire template_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Template _input_ and _reference_ variable names have their own namespaces. The `hero` in `let hero` is never the same | 
					
						
							|  |  |  | variable as the `hero` declared as `#hero`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a one-per-element} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### One structural directive per host element
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-06 10:43:33 +00:00
										 |  |  | Someday you'll want to repeat a block of HTML but only when a particular condition is true. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | You'll _try_ to put both an `*ngFor` and an `*ngIf` on the same host element. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Angular won't let you. You may apply only one _structural_ directive to an element. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The reason is simplicity. Structural directives can do complex things with the host element and its descendents. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | When two directives lay claim to the same host element, which one takes precedence? | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Which should go first, the `NgIf` or the `NgFor`? Can the `NgIf` cancel the effect of the `NgFor`? | 
					
						
							|  |  |  | If so (and it seems like it should be so), how should Angular generalize the ability to cancel for other structural directives? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There are no easy answers to these questions. Prohibiting multiple structural directives makes them moot. | 
					
						
							|  |  |  | There's an easy solution for this use case: put the `*ngIf` on a container element that wraps the `*ngFor` element. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | One or both elements can be an [`ng-container`](guide/structural-directives#ngcontainer) so you don't have to introduce extra levels of HTML. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | {@a ngSwitch} | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | ## Inside _NgSwitch_ directives
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The Angular _NgSwitch_ is actually a set of cooperating directives: `NgSwitch`, `NgSwitchCase`, and `NgSwitchDefault`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here's an example. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngswitch)" region="ngswitch"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The switch value assigned to `NgSwitch` (`hero.emotion`) determines which | 
					
						
							|  |  |  | (if any) of the switch cases are displayed. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | `NgSwitch` itself is not a structural directive. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | It's an _attribute_ directive that controls the behavior of the other two switch directives. | 
					
						
							|  |  |  | That's why you write `[ngSwitch]`, never `*ngSwitch`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | `NgSwitchCase` and `NgSwitchDefault` _are_ structural directives. | 
					
						
							|  |  |  | You attach them to elements using the asterisk (*) prefix notation. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | An `NgSwitchCase` displays its host element when its value matches the switch value. | 
					
						
							|  |  |  | The `NgSwitchDefault` displays its host element when no sibling `NgSwitchCase` matches the switch value. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | The element to which you apply a directive is its _host_ element. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The `<happy-hero>` is the host element for the happy `*ngSwitchCase`. | 
					
						
							|  |  |  | The `<unknown-hero>` is the host element for the `*ngSwitchDefault`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | As with other structural directives, the `NgSwitchCase` and `NgSwitchDefault` | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | can be desugared into the template _attribute_ form. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngswitch-template-attr)" region="ngswitch-template-attr"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | That, in turn, can be desugared into the `<ng-template>` element form. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngswitch-template)" region="ngswitch-template"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | {@a prefer-asterisk} | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | ## Prefer the asterisk (*) syntax.
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The asterisk (*) syntax is more clear than the other desugared forms. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | Use [<ng-container>](guide/structural-directives#ng-container) when there's no single element | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | to host the directive. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | While there's rarely a good reason to apply a structural directive in template _attribute_ or _element_ form, | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | it's still important to know that Angular creates a `<ng-template>` and to understand how it works. | 
					
						
							|  |  |  | You'll refer to the `<ng-template>` when you [write your own structural directive](guide/structural-directives#unless). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a template} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | ## The *<ng-template>*
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | The <ng-template> is an Angular element for rendering HTML. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | It is never displayed directly. | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | In fact, before rendering the view, Angular _replaces_ the `<ng-template>` and its contents with a comment. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | If there is no structural directive and you merely wrap some elements in a `<ng-template>`, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | those elements disappear. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | That's the fate of the middle "Hip!" in the phrase "Hip! Hip! Hooray!". | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (template-tag)" region="template-tag"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Angular erases the middle "Hip!", leaving the cheer a bit less enthusiastic. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							| 
									
										
										
										
											2017-05-11 21:44:22 +02:00
										 |  |  |   <img src='generated/images/guide/structural-directives/template-rendering.png' alt="template tag rendering"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | A structural directive puts a `<ng-template>` to work | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | as you'll see when you [write your own structural directive](guide/structural-directives#unless). | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a ngcontainer} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a ng-container} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | ## Group sibling elements with <ng-container>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There's often a _root_ element that can and should host the structural directive. | 
					
						
							|  |  |  | The list element (`<li>`) is a typical host element of an `NgFor` repeater. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngfor-li)" region="ngfor-li"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | When there isn't a host element, you can usually wrap the content in a native HTML container element, | 
					
						
							|  |  |  | such as a `<div>`, and attach the directive to that wrapper. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif)" region="ngif"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | Introducing another container element—typically a `<span>` or `<div>`—to | 
					
						
							|  |  |  | group the elements under a single _root_ is usually harmless. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | _Usually_ ... but not _always_. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | The grouping element may break the template appearance because CSS styles | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | neither expect nor accommodate the new layout. | 
					
						
							|  |  |  | For example, suppose you have the following paragraph layout. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-span)" region="ngif-span"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | You also have a CSS style rule that happens to apply to a `<span>` within a `<p>`aragraph. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.css" linenums="false" title="src/app/app.component.css (p-span)" region="p-span"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The constructed paragraph renders strangely. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/bad-paragraph.png' alt="spanned paragraph with bad style"> | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The `p span` style, intended for use elsewhere, was inadvertently applied here. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Another problem: some HTML elements require all immediate children to be of a specific type. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | For example, the `<select>` element requires `<option>` children. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | You can't wrap the _options_ in a conditional `<div>` or a `<span>`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When you try this, | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (select-span)" region="select-span"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | the drop down is empty. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/bad-select.png' alt="spanned options don't work"> | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The browser won't display an `<option>` within a `<span>`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### <ng-container> to the rescue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The Angular `<ng-container>` is a grouping element that doesn't interfere with styles or layout | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | because Angular _doesn't put it in the DOM_. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Here's the conditional paragraph again, this time using `<ng-container>`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-ngcontainer)" region="ngif-ngcontainer"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | It renders properly. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/good-paragraph.png' alt="ngcontainer paragraph with proper style"> | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Now conditionally exclude a _select_ `<option>` with `<ng-container>`. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (select-ngcontainer)" region="select-ngcontainer"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The drop down works properly. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/select-ngcontainer-anim.gif' alt="ngcontainer options work properly"> | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The `<ng-container>` is a syntax element recognized by the Angular parser. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | It's not a directive, component, class, or interface. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | It's more like the curly braces in a JavaScript `if`-block: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | <code-example language="javascript"> | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  |   if (someCondition) { | 
					
						
							|  |  |  |     statement1; | 
					
						
							|  |  |  |     statement2; | 
					
						
							|  |  |  |     statement3; | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Without those braces, JavaScript would only execute the first statement | 
					
						
							|  |  |  | when you intend to conditionally execute all of them as a single block. | 
					
						
							|  |  |  | The `<ng-container>` satisfies a similar need in Angular templates. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a unless} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Write a structural directive
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | In this section, you write an `UnlessDirective` structural directive | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | that does the opposite of `NgIf`. | 
					
						
							|  |  |  | `NgIf` displays the template content when the condition is `true`. | 
					
						
							|  |  |  | `UnlessDirective` displays the content when the condition is ***false***. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (myUnless-1)" region="myUnless-1"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Creating a directive is similar to creating a component. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | * Import the `Directive` decorator (instead of the `Component` decorator). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | * Import the `Input`, `TemplateRef`, and `ViewContainerRef` symbols; you'll need them for _any_ structural directive. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | * Apply the decorator to the directive class. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | * Set the CSS *attribute selector* that identifies the directive when applied to an element in a template. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Here's how you might begin: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/unless.directive.ts" linenums="false" title="src/app/unless.directive.ts (skeleton)" region="skeleton"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | The directive's _selector_ is typically the directive's **attribute name** in square brackets, `[myUnless]`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | The brackets define a CSS | 
					
						
							| 
									
										
										
										
											2017-04-24 20:23:45 +02:00
										 |  |  | <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors" title="MDN: Attribute selectors">attribute selector</a>. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The directive _attribute name_ should be spelled in _lowerCamelCase_ and begin with a prefix. | 
					
						
							|  |  |  | Don't use `ng`. That prefix belongs to Angular. | 
					
						
							|  |  |  | Pick something short that fits you or your company. | 
					
						
							|  |  |  | In this example, the prefix is `my`. | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-21 17:21:45 -07:00
										 |  |  | The directive _class_ name ends in `Directive` per the [style guide](guide/styleguide#02-03 "Angular Style Guide"). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Angular's own directives do not. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### _TemplateRef_ and _ViewContainerRef_
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | A simple structural directive like this one creates an | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [_embedded view_](api/core/EmbeddedViewRef "API: EmbeddedViewRef") | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | from the Angular-generated `<ng-template>` and inserts that view in a | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [_view container_](api/core/ViewContainerRef "API: ViewContainerRef") | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | adjacent to the directive's original `<p>` host element. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | You'll acquire the `<ng-template>` contents with a | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [`TemplateRef`](api/core/TemplateRef "API: TemplateRef") | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | and access the _view container_ through a | 
					
						
							| 
									
										
										
										
											2017-04-30 22:10:32 +02:00
										 |  |  | [`ViewContainerRef`](api/core/ViewContainerRef "API: ViewContainerRef"). | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | You inject both in the directive constructor as private variables of the class. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/unless.directive.ts" linenums="false" title="src/app/unless.directive.ts (ctor)" region="ctor"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ### The _myUnless_ property
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The directive consumer expects to bind a true/false condition to `[myUnless]`. | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | That means the directive needs a `myUnless` property, decorated with `@Input` | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | <div class="l-sub-section"> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Read about `@Input` in the [_Template Syntax_](guide/template-syntax#inputs-outputs) guide. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-10 16:51:13 +01:00
										 |  |  | </div> | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/unless.directive.ts" linenums="false" title="src/app/unless.directive.ts (set)" region="set"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | Angular sets the  `myUnless` property whenever the value of the condition changes. | 
					
						
							|  |  |  | Because the `myUnless` property does work, it needs a setter. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * If the condition is falsy and the view hasn't been created previously, | 
					
						
							|  |  |  | tell the _view container_ to create the _embedded view_ from the template. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | * If the condition is truthy and the view is currently displayed, | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | clear the container which also destroys the view. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Nobody reads the `myUnless` property so it doesn't need a getter. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The completed directive code looks like this: | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/unless.directive.ts" linenums="false" title="src/app/unless.directive.ts (excerpt)" region="no-docs"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-31 12:23:16 +01:00
										 |  |  | Add this directive to the `declarations` array of the AppModule. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Then create some HTML to try it. | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (myUnless)" region="myUnless"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </code-example> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | When the `condition` is falsy, the top (A) paragraph appears and the bottom (B) paragraph disappears. | 
					
						
							|  |  |  | When the `condition` is truthy, the top (A) paragraph is removed and the bottom (B) paragraph appears. | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-30 20:04:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-09 23:53:32 +01:00
										 |  |  | <figure> | 
					
						
							|  |  |  |   <img src='generated/images/guide/structural-directives/unless-anim.gif' alt="UnlessDirective in action"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | </figure> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | {@a summary} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | ## Summary
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 15:11:02 +03:00
										 |  |  | You can both try and download the source code for this guide in the <live-example></live-example>. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | Here is the source from the `src/app/` folder. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | <code-tabs> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="app.component.ts" path="structural-directives/src/app/app.component.ts"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="app.component.html" path="structural-directives/src/app/app.component.html"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   <code-pane title="app.component.css" path="structural-directives/src/app/app.component.css"> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="app.module.ts" path="structural-directives/src/app/app.module.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="hero.ts" path="structural-directives/src/app/hero.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="hero-switch.components.ts" path="structural-directives/src/app/hero-switch.components.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   <code-pane title="unless.directive.ts" path="structural-directives/src/app/unless.directive.ts"> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  |   </code-pane> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-27 16:08:53 +01:00
										 |  |  | </code-tabs> | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-01 01:57:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | You learned | 
					
						
							| 
									
										
										
										
											2017-03-11 13:44:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * that structural directives manipulate HTML layout. | 
					
						
							| 
									
										
										
										
											2017-03-11 15:36:40 +00:00
										 |  |  | * to use [`<ng-container>`](guide/structural-directives#ngcontainer) as a grouping element when there is no suitable host element. | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | * that the Angular desugars [asterisk (*) syntax](guide/structural-directives#asterisk) into a `<ng-template>`. | 
					
						
							| 
									
										
										
										
											2017-02-22 18:09:39 +00:00
										 |  |  | * how that works for the `NgIf`, `NgFor` and `NgSwitch` built-in directives. | 
					
						
							| 
									
										
										
										
											2017-04-12 21:53:18 +02:00
										 |  |  | * about the [_microsyntax_](guide/structural-directives#microsyntax) that expands into a [`<ng-template>`](guide/structural-directives#template). | 
					
						
							| 
									
										
										
										
											2017-04-24 20:23:45 +02:00
										 |  |  | * to write a [custom structural directive](guide/structural-directives#unless), `UnlessDirective`. |