| 
									
										
										
										
											2016-02-05 23:27:06 -08:00
										 |  |  |  | include ../_util-fns | 
					
						
							| 
									
										
										
										
											2016-01-21 09:49:13 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | +includeShared('{ts}', 'intro') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   The complete source code for the example app in this chapter is | 
					
						
							|  |  |  |  |   [in GitHub](https://github.com/angular/angular.io/tree/master/public/docs/_examples/template-syntax/dart). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'html-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'my-first-app')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'html-2') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'interpolation-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'first-interpolation')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'interpolation-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'title+image')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'interpolation-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'sum-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'interpolation-4') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'sum-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'interpolation-5') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'template-expressions-1') | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   We write template expressions in a language that looks like Dart. | 
					
						
							|  |  |  |  |   Many Dart expressions are legal template expressions, but not all. | 
					
						
							|  |  |  |  |   Dart expressions that have or promote side effects are prohibited, | 
					
						
							|  |  |  |  |   including: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   * assignments (`=`, `+=`, `-=`, ...) | 
					
						
							|  |  |  |  |   * creating instances using `new` or `const` | 
					
						
							|  |  |  |  |   * increment and decrement (`++` and `--`) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   Other notable differences from Dart syntax include: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   * no support for Dart string interpolation; for example, | 
					
						
							|  |  |  |  |     instead of `"'The title is $title'"`, you must use | 
					
						
							|  |  |  |  |     `"'The title is ' + title"` | 
					
						
							|  |  |  |  |   * no support for the bitwise operators `|` and `&` | 
					
						
							|  |  |  |  |   * new [template expression operators](#expression-operators), such as `|` | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'template-expressions-context') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'template-expressions-guidelines') | 
					
						
							| 
									
										
										
										
											2016-01-21 09:49:13 -08:00
										 |  |  |  | :marked | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  |   Dependent values should not change during a single turn of the event loop. | 
					
						
							|  |  |  |  |   If an idempotent expression returns a string or a number, it returns the same string or number | 
					
						
							|  |  |  |  |   when called twice in a row. If the expression returns an object (including a `DateTime`, `Map`, or `List`), | 
					
						
							|  |  |  |  |   it returns the same object *reference* when called twice in a row. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .callout.is-helpful | 
					
						
							|  |  |  |  |   header Dart difference: Arrays are lists | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     Arrays in JavaScript correspond to lists in Dart | 
					
						
							|  |  |  |  |     (instances of the `List` class). | 
					
						
							|  |  |  |  |     This chapter uses _array_ and _list_ interchangeably. | 
					
						
							|  |  |  |  |     For more information, see | 
					
						
							|  |  |  |  |     [Lists](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#lists) | 
					
						
							|  |  |  |  |     in the [Dart language tour](https://www.dartlang.org/docs/dart-up-and-running/ch02.html). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'template-statements-1') | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   Like template expressions, template *statements* use a language that looks like Dart. | 
					
						
							|  |  |  |  |   The template statement parser is different than the template expression parser and | 
					
						
							|  |  |  |  |   specifically supports both basic assignment (`=`) and chaining expressions with semicolons (`;`). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   However, certain Dart syntax is not allowed: | 
					
						
							|  |  |  |  |   * the `new` and `const` keywords | 
					
						
							|  |  |  |  |   * increment and decrement operators, `++` and `--` | 
					
						
							|  |  |  |  |   * operator assignment, such as `+=` and `-=` | 
					
						
							|  |  |  |  |   * the operators `|` and `&` (neither for bitwise operations | 
					
						
							|  |  |  |  |     nor for the Angular [pipe operator](#the-pipe-operator-)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'template-statements-3') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'img+button')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'hero-detail-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'disabled-button-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-4') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-attribute-vs-property') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-5') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-world-without-attributes') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-targets') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <div width="90%"> | 
					
						
							|  |  |  |  | table | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     th Binding type | 
					
						
							|  |  |  |  |     th Target | 
					
						
							|  |  |  |  |     th Examples | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     td Property | 
					
						
							|  |  |  |  |     td. | 
					
						
							|  |  |  |  |       Element property<br> | 
					
						
							|  |  |  |  |       Component property<br> | 
					
						
							|  |  |  |  |       Directive property | 
					
						
							|  |  |  |  |     td | 
					
						
							|  |  |  |  |       +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-syntax-1')(format=".") | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     td Event | 
					
						
							|  |  |  |  |     td. | 
					
						
							|  |  |  |  |       Element event<br> | 
					
						
							|  |  |  |  |       Component event<br> | 
					
						
							|  |  |  |  |       Directive event | 
					
						
							|  |  |  |  |     td | 
					
						
							|  |  |  |  |       +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-syntax-1')(format=".") | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     td Two-way | 
					
						
							|  |  |  |  |     td. | 
					
						
							|  |  |  |  |       Event and property | 
					
						
							|  |  |  |  |     td | 
					
						
							|  |  |  |  |       +makeExample('template-syntax/dart/lib/app_component.html', '2-way-binding-syntax-1')(format=".") | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     td Attribute | 
					
						
							|  |  |  |  |     td. | 
					
						
							|  |  |  |  |       Attribute | 
					
						
							|  |  |  |  |       (the exception) | 
					
						
							|  |  |  |  |     td | 
					
						
							|  |  |  |  |       +makeExample('template-syntax/dart/lib/app_component.html', 'attribute-binding-syntax-1')(format=".") | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     td Class | 
					
						
							|  |  |  |  |     td. | 
					
						
							|  |  |  |  |       <code>class</code> property | 
					
						
							|  |  |  |  |     td | 
					
						
							|  |  |  |  |       +makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-syntax-1')(format=".") | 
					
						
							|  |  |  |  |   tr | 
					
						
							|  |  |  |  |     td Style | 
					
						
							|  |  |  |  |     td. | 
					
						
							|  |  |  |  |       <code>style</code> property | 
					
						
							|  |  |  |  |     td | 
					
						
							|  |  |  |  |       +makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-syntax-1')(format=".") | 
					
						
							|  |  |  |  | </div> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'binding-syntax-end') | 
					
						
							| 
									
										
										
										
											2016-01-21 09:49:13 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | +includeShared('{ts}', 'property-binding-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-4') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-5') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-6') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-7') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-8') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-5')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-9') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-10') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-11') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-6')(format=".") | 
					
						
							|  |  |  |  | .callout.is-helpful | 
					
						
							|  |  |  |  |   header Dart difference: Type exceptions | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     In checked mode, uncommenting the `<hero-detail>` element above causes a type exception, | 
					
						
							|  |  |  |  |     because `String` isn't a subtype of `Hero`. | 
					
						
							|  |  |  |  |     For information on checked mode, see [Important concepts](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#important-concepts) | 
					
						
							|  |  |  |  |     in the Dart language tour. | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-12') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-7')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-13') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-vs-interpolation')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'property-binding-14') | 
					
						
							| 
									
										
										
										
											2016-01-21 09:49:13 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | +includeShared('{ts}', 'other-bindings-1') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-colspan')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-aria')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-class-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-class-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-2')(format=".") | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  |   +includeShared('{ts}', 'other-bindings-class-3') | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   Finally, we can bind to a specific class name. | 
					
						
							|  |  |  |  |   Angular adds the class when the template expression evaluates to `true`. | 
					
						
							|  |  |  |  |   It removes the class when the expression evaluates to `false`. | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-class-4') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-style-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-style-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'other-bindings-style-3') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-4') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-5') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-6') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/hero_detail_component.dart', | 
					
						
							|  |  |  |  | 'template-1', 'HeroDetailComponent.ts (template)')(format=".") | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/hero_detail_component.dart', | 
					
						
							|  |  |  |  | 'deleteRequest', 'HeroDetailComponent.ts (delete logic)')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-7') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-to-component')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'event-binding-8') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-4') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-5') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-6') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-4')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ngModel-7') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-2') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngClass-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-3a')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngClass-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.dart', 'setClasses')(format=".") | 
					
						
							|  |  |  |  | // PENDING: Add "Dart difference" for returning maps in Dart? for omitting unnecessary `this.`s? | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngClass-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgClass-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngStyle-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngStyle-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.dart', 'setStyles')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngStyle-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-2')(format=".") | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  |   +includeShared('{ts}', 'directives-ngIf-1') | 
					
						
							|  |  |  |  | <a id="ngIf"></a> | 
					
						
							|  |  |  |  | .l-main-section | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   ### NgIf | 
					
						
							|  |  |  |  |   We can add an element subtree (an element and its children) to the DOM  by binding an `NgIf` directive to a `true` expression. | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngIf-2') | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  |   +includeShared('{ts}', 'directives-ngIf-3') | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   Binding to a false expression removes the element subtree from the DOM. | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-2')(format=".") | 
					
						
							|  |  |  |  | .callout.is-helpful | 
					
						
							|  |  |  |  |   header Dart difference: No truthy values | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     In checked mode, Dart expects Boolean values | 
					
						
							|  |  |  |  |     (those with type `bool`) to be either `true` or `false`. | 
					
						
							|  |  |  |  |     Even in production mode, the only value Dart treats as `true` is | 
					
						
							|  |  |  |  |     the value `true`; all other values are `false`. | 
					
						
							|  |  |  |  |     TypeScript and JavaScript, on the other hand, treat | 
					
						
							|  |  |  |  |     many values (including non-null objects) as true. | 
					
						
							|  |  |  |  |     A TypeScript Angular 2 program, for example, often has code like | 
					
						
							|  |  |  |  |     `*ngIf="currentHero"` where a Dart program has code like | 
					
						
							|  |  |  |  |     `*ngIf="currentHero != null"`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     When converting TypeScript code to Dart code, watch out for | 
					
						
							|  |  |  |  |     true/false problems. For example, forgetting the `!= null` | 
					
						
							|  |  |  |  |     can lead to exceptions in checked mode, such as | 
					
						
							|  |  |  |  |     "EXCEPTION: type 'Hero' is not a subtype of type 'bool' of 'boolean expression'". | 
					
						
							|  |  |  |  |     For more information, see | 
					
						
							|  |  |  |  |     [Booleans](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#booleans) | 
					
						
							|  |  |  |  |     in the [Dart language tour](https://www.dartlang.org/docs/dart-up-and-running/ch02.html). | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngIf-4') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngIf-5') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngSwitch-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgSwitch')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngSwitch-2') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-3') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-4') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-5') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-6') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngFor-7') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngForTrackBy-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.dart', 'trackByHeroes')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngForTrackBy-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgForTrackBy-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'directives-ngForTrackBy-3') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngIf-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'Template-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngIf-2a') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'Template-2a')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngIf-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'Template-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngIf-3') | 
					
						
							|  |  |  |  | // Changed from RED to ORANGE, since this isn't so dire a situation in Dart. | 
					
						
							|  |  |  |  | .callout.is-important | 
					
						
							|  |  |  |  |   header Remember the brackets! | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     Don’t make the mistake of writing `ngIf="currentHero"`! | 
					
						
							|  |  |  |  |     That syntax assigns the *string* value "currentHero" to `ngIf`, | 
					
						
							|  |  |  |  |     which won't work because `ngIf` expects a bool. | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngSwitch-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'NgSwitch-expanded')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngSwitch-2') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngFor-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'Template-3a')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngFor-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'Template-3')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngFor-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'Template-4')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'star-template-ngFor-4') | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-30 07:01:16 -07:00
										 |  |  |  | +includeShared('{ts}', 'ref-vars') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'ref-phone')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ref-vars-value') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ref-vars-form-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'ref-form')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ref-vars-form-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'ref-form-a')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'ref-vars-form-3') | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'inputs-outputs-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'io-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'inputs-outputs-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'io-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'inputs-outputs-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/hero_detail_component.dart', 'input-output-1')(format=".") | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     Alternatively, we can identify members in the `inputs` and `outputs` arrays | 
					
						
							|  |  |  |  |     of the directive metadata, as in this example: | 
					
						
							|  |  |  |  |   +makeExample('template-syntax/dart/lib/hero_detail_component.dart', 'input-output-2')(format=".") | 
					
						
							|  |  |  |  |   <br> | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     We can specify an input/output property either with a decorator or in a metadata array. | 
					
						
							|  |  |  |  |     Don't do both! | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'inputs-outputs-4') | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'inputs-outputs-5') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'my-click')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'inputs-outputs-6') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/my_click_directive.dart', 'my-click-output-1')(format=".") | 
					
						
							|  |  |  |  | .l-sub-section | 
					
						
							|  |  |  |  |   :marked | 
					
						
							|  |  |  |  |     We can also alias property names in the `inputs` and `outputs` arrays. | 
					
						
							|  |  |  |  |     We write a colon-delimited (`:`) string with | 
					
						
							|  |  |  |  |     the directive property name on the *left* and the public alias on the *right*: | 
					
						
							|  |  |  |  |   +makeExample('template-syntax/dart/lib/my_click_directive.dart', 'my-click-output-2')(format=".") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <a id="expression-operators"></a> | 
					
						
							|  |  |  |  | .l-main-section | 
					
						
							|  |  |  |  | :marked | 
					
						
							|  |  |  |  |   ## Template expression operators | 
					
						
							|  |  |  |  |   The template expression language employs a subset of Dart syntax supplemented with a few special operators | 
					
						
							| 
									
										
										
										
											2016-04-22 22:57:41 +02:00
										 |  |  |  |   for specific scenarios. We'll cover two of these operators: _pipe_ and _safe navigation operator_. | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | .callout.is-helpful | 
					
						
							|  |  |  |  |   header Dart difference: ?. is a Dart operator | 
					
						
							|  |  |  |  |   :marked | 
					
						
							| 
									
										
										
										
											2016-04-22 22:57:41 +02:00
										 |  |  |  |     The safe navigation operator (`?.`) is part of the Dart language. | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  |     It's considered a template expression operator because | 
					
						
							|  |  |  |  |     Angular 2 supports `?.` even in TypeScript and JavaScript apps. | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'expression-operators-pipe-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'pipes-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'expression-operators-pipe-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'pipes-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'expression-operators-pipe-3') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'pipes-3')(format=".") | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  |   NOTE: Intentionally omit discussion of the json pipe. | 
					
						
							|  |  |  |  |   +includeShared('{ts}', 'expression-operators-pipe-4') | 
					
						
							|  |  |  |  |   +makeExample('template-syntax/dart/lib/app_component.html', 'pipes-json')(format=".") | 
					
						
							| 
									
										
										
										
											2016-04-22 22:57:41 +02:00
										 |  |  |  | +includeShared('{ts}', 'expression-operators-safe-1') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'safe-2')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'expression-operators-safe-2') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'safe-1')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'expression-operators-safe-3') | 
					
						
							|  |  |  |  | // +includeShared('{ts}', 'expression-operators-safe-4') | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | :marked | 
					
						
							|  |  |  |  |   Dart throws an exception, and so does Angular: | 
					
						
							|  |  |  |  | code-example(format="" language="html"). | 
					
						
							|  |  |  |  |   EXCEPTION: The null object does not have a getter 'firstName'. | 
					
						
							| 
									
										
										
										
											2016-04-22 22:57:41 +02:00
										 |  |  |  | +includeShared('{ts}', 'expression-operators-safe-5') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'safe-4')(format=".") | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // | 
					
						
							|  |  |  |  |   NOTE: Intentionally skip ugly null checking you wouldn't do in Dart. | 
					
						
							| 
									
										
										
										
											2016-04-22 22:57:41 +02:00
										 |  |  |  |   That means skipping the shared sections 'expression-operators-safe-6' & 7, | 
					
						
							|  |  |  |  |   plus the example 'safe-5'. | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | :marked | 
					
						
							|  |  |  |  |   This approach has merit but can be cumbersome, especially if the property path is long. | 
					
						
							|  |  |  |  |   Imagine guarding against a null somewhere in a long property path such as `a.b.c.d`. | 
					
						
							| 
									
										
										
										
											2016-04-22 22:57:41 +02:00
										 |  |  |  | +includeShared('{ts}', 'expression-operators-safe-8') | 
					
						
							|  |  |  |  | +makeExample('template-syntax/dart/lib/app_component.html', 'safe-6')(format=".") | 
					
						
							|  |  |  |  | +includeShared('{ts}', 'expression-operators-safe-9') | 
					
						
							| 
									
										
										
										
											2016-01-21 09:49:13 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 11:43:15 -08:00
										 |  |  |  | +includeShared('{ts}', 'summary') |