801 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			801 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!-- #docplaster -->
 | 
						|
<a id="toc"></a>
 | 
						|
<h1>Template Syntax</h1>
 | 
						|
<a href="#interpolation">Interpolation</a><br>
 | 
						|
<a href="#mental-model">Mental Model</a><br>
 | 
						|
<a href="#buttons">Buttons</a><br>
 | 
						|
<a href="#prop-vs-attrib">Properties vs. Attributes</a><br>
 | 
						|
<br>
 | 
						|
<a href="#property-binding">Property Binding</a><br>
 | 
						|
<div style="margin-left:8px">
 | 
						|
  <a href="#attribute-binding">Attribute Binding</a><br>
 | 
						|
  <a href="#class-binding">Class Binding</a><br>
 | 
						|
  <a href="#style-binding">Style Binding</a><br>
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
<a href="#event-binding">Event Binding</a><br>
 | 
						|
 | 
						|
<br>
 | 
						|
<div>Directives</div>
 | 
						|
<div style="margin-left:8px">
 | 
						|
  <a href="#ngModel">NgModel (two-way) Binding</a><br>
 | 
						|
  <a href="#ngClass">NgClass Binding</a><br>
 | 
						|
  <a href="#ngStyle">NgStyle Binding</a><br>
 | 
						|
  <a href="#ngIf">NgIf</a><br>
 | 
						|
  <a href="#ngSwitch">NgSwitch</a><br>
 | 
						|
  <a href="#ngFor">NgFor</a><br>
 | 
						|
  <div style="margin-left:8px">
 | 
						|
    <a href="#ngFor-index">NgFor with index</a><br>
 | 
						|
    <a href="#ngFor-trackBy">NgFor with trackBy</a><br>
 | 
						|
  </div>
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
<a href="#star-prefix">* prefix and <template></a><br>
 | 
						|
<a href="#local-vars">Template local variables</a><br>
 | 
						|
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
 | 
						|
<a href="#pipes">Pipes</a><br>
 | 
						|
<a href="#elvis">Elvis <i>?.</i></a><br>
 | 
						|
<!--<a href="#enums">Enums</a><br>-->
 | 
						|
 | 
						|
<!-- Interpolation and expressions -->
 | 
						|
<hr><h2 id="interpolation">Interpolation</h2>
 | 
						|
 | 
						|
<!-- #docregion first-interpolation -->
 | 
						|
<p>My current hero is {{currentHero.firstName}}</p>
 | 
						|
<!-- #enddocregion first-interpolation -->
 | 
						|
 | 
						|
<!-- #docregion title+image -->
 | 
						|
<h3>
 | 
						|
  {{title}}
 | 
						|
  <img src="{{heroImageUrl}}" style="height:30px">
 | 
						|
</h3>
 | 
						|
<!-- #enddocregion title+image -->
 | 
						|
 | 
						|
<!-- #docregion sum-1 -->
 | 
						|
<!-- "The sum of 1 + 1 is 2" -->
 | 
						|
<p>The sum of 1 + 1 is {{1 + 1}}</p>
 | 
						|
<!-- #enddocregion sum-1 -->
 | 
						|
 | 
						|
<!-- #docregion sum-2 -->
 | 
						|
<!-- "The sum of 1 + 1 is not 4" -->
 | 
						|
<p>The sum of 1 + 1 is not {{1 + 1 + getVal()}}</p>
 | 
						|
<!-- #enddocregion sum-2 -->
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- New Mental Model -->
 | 
						|
<hr><h2 id="mental-model">New Mental Model</h2>
 | 
						|
 | 
						|
<!--<img src="http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png">-->
 | 
						|
<!-- Public Domain terms of use: http://www.wpclipart.com/terms.html -->
 | 
						|
<!-- #docregion img+button -->
 | 
						|
<div class="special">Mental Model</div>
 | 
						|
<img src="assets/images/hero.png">
 | 
						|
<button disabled>Save</button>
 | 
						|
<!-- #enddocregion img+button -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion hero-detail-1 -->
 | 
						|
  <!-- Normal HTML -->
 | 
						|
  <div class="special">Mental Model</div>
 | 
						|
  <!-- Wow! A new element! -->
 | 
						|
  <hero-detail></hero-detail>
 | 
						|
  <!-- #enddocregion hero-detail-1 -->
 | 
						|
</div>
 | 
						|
<br><br>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion disabled-button-1 -->
 | 
						|
  <!-- Bind button disabled state to `isUnchanged` property -->
 | 
						|
  <button [disabled]="isUnchanged">Save</button>
 | 
						|
  <!-- #enddocregion disabled-button-1 -->
 | 
						|
</div>
 | 
						|
<br><br>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion property-binding-syntax-1 -->
 | 
						|
  <img [src] = "heroImageUrl">
 | 
						|
  <hero-detail [hero]="currentHero"></hero-detail>
 | 
						|
  <div [ngClass] = "{selected: isSelected}"></div>
 | 
						|
  <!-- #enddocregion property-binding-syntax-1 -->
 | 
						|
</div>
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- #docregion event-binding-syntax-1 -->
 | 
						|
<button (click) = "onSave()">Save</button>
 | 
						|
<hero-detail (deleteRequest)="deleteHero()"></hero-detail>
 | 
						|
<div (myClick)="clickity=$event">click me</div>
 | 
						|
<!-- #enddocregion event-binding-syntax-1 -->
 | 
						|
{{clickity}}
 | 
						|
<br><br>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion 2-way-binding-syntax-1 -->
 | 
						|
  <input [(ngModel)]="heroName">
 | 
						|
  <!-- #enddocregion 2-way-binding-syntax-1 -->
 | 
						|
  Hero Name: {{heroName}}
 | 
						|
</div>
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- #docregion attribute-binding-syntax-1 -->
 | 
						|
<button [attr.aria-label]="help">help</button>
 | 
						|
<!-- #enddocregion attribute-binding-syntax-1 -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- #docregion class-binding-syntax-1 -->
 | 
						|
<div [class.special]="isSpecial">Special</div>
 | 
						|
<!-- #enddocregion class-binding-syntax-1 -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- #docregion style-binding-syntax-1 -->
 | 
						|
<button [style.color] = "isSpecial ? 'red' : 'green'">
 | 
						|
<!-- #enddocregion style-binding-syntax-1 -->
 | 
						|
button</button>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- property vs. attribute -->
 | 
						|
<hr><h2 id="prop-vs-attrib">Property vs. Attribute (img examples)</h2>
 | 
						|
<!-- examine the following <img> tag in the browser tools -->
 | 
						|
<img src="assets/images/ng-logo.png"
 | 
						|
     [src]="heroImageUrl">
 | 
						|
 | 
						|
<br><br>
 | 
						|
 | 
						|
<img [src]="iconUrl"/>
 | 
						|
<img bind-src="heroImageUrl"/>
 | 
						|
<img [attr.src]="villainImageUrl"/>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- buttons -->
 | 
						|
<hr><h2 id="buttons">Buttons</h2>
 | 
						|
 | 
						|
<button>Enabled (but does nothing)</button>
 | 
						|
<button disabled>Disabled</button>
 | 
						|
<button disabled=false>Still disabled</button>
 | 
						|
<br><br>
 | 
						|
<button disabled>disabled by attribute</button>
 | 
						|
<button [disabled]="isUnchanged">disabled by property binding</button>
 | 
						|
<br><br>
 | 
						|
<button bind-disabled="isUnchanged" on-click="onSave($event)">Disabled Cancel</button>
 | 
						|
<button [disabled]="!canSave" (click)="onSave($event)">Enabled Save</button>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- property binding -->
 | 
						|
<hr><h2 id="property-binding">Property Binding</h2>
 | 
						|
 | 
						|
<!-- #docregion property-binding-1 -->
 | 
						|
<img [src]="heroImageUrl">
 | 
						|
<!-- #enddocregion property-binding-1 -->
 | 
						|
<!-- #docregion property-binding-2 -->
 | 
						|
<button [disabled]="isUnchanged">Cancel is disabled</button>
 | 
						|
<!-- #enddocregion property-binding-2 -->
 | 
						|
<!-- #docregion property-binding-3 -->
 | 
						|
<div [ngClass]="classes">[ngClass] binding to the classes property</div>
 | 
						|
<!-- #enddocregion property-binding-3 -->
 | 
						|
<!-- #docregion property-binding-4 -->
 | 
						|
<hero-detail [hero]="currentHero"></hero-detail>
 | 
						|
<!-- #enddocregion property-binding-4 -->
 | 
						|
<!-- #docregion property-binding-5 -->
 | 
						|
<img bind-src="heroImageUrl">
 | 
						|
<!-- #enddocregion property-binding-5 -->
 | 
						|
 | 
						|
<!-- #docregion property-binding-6 -->
 | 
						|
  <!-- BAD! HeroDetailComponent.hero expects a Hero object,
 | 
						|
  not the string "currentHero".
 | 
						|
 | 
						|
  <hero-detail hero="currentHero"></hero-detail> -->
 | 
						|
<!-- #enddocregion property-binding-6 -->
 | 
						|
 | 
						|
<!--  In checked mode, uncommenting the hero-detail above causes this:
 | 
						|
    EXCEPTION: type 'String' is not a subtype of type 'Hero' of 'value'. -->
 | 
						|
 | 
						|
<!-- #docregion property-binding-7 -->
 | 
						|
<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>
 | 
						|
<!-- #enddocregion property-binding-7 -->
 | 
						|
 | 
						|
<!-- #docregion property-binding-vs-interpolation -->
 | 
						|
Interpolated: <img src="{{heroImageUrl}}"><br>
 | 
						|
Property bound: <img [src]="heroImageUrl">
 | 
						|
 | 
						|
<div>The interpolated title is {{title}}</div>
 | 
						|
<div [textContent]="'The [textContent] title is '+title"></div>
 | 
						|
<!-- #enddocregion property-binding-vs-interpolation -->
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- attribute binding -->
 | 
						|
<hr><h2 id="attribute-binding">Attribute Binding</h2>
 | 
						|
 | 
						|
<!--  create and set a colspan attribute -->
 | 
						|
<!-- #docregion attrib-binding-colspan -->
 | 
						|
<table border=1>
 | 
						|
  <!--  expression calculates colspan=2 -->
 | 
						|
  <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
 | 
						|
 | 
						|
  <!-- ERROR: There is no `colspan` property to set!
 | 
						|
    <tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
 | 
						|
  -->
 | 
						|
 | 
						|
  <tr><td>Five</td><td>Six</td></tr>
 | 
						|
</table>
 | 
						|
<!-- #enddocregion attrib-binding-colspan -->
 | 
						|
 | 
						|
<br>
 | 
						|
<!-- #docregion attrib-binding-aria -->
 | 
						|
<!-- create and set an aria attribute for assistive technology -->
 | 
						|
<button [attr.aria-label]="actionName">{{actionName}} with Aria</button>
 | 
						|
<!-- #enddocregion attrib-binding-aria -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- The following effects are not discussed in the chapter -->
 | 
						|
<div>
 | 
						|
  <!-- any use of [attr.disabled] creates the disabled attribute -->
 | 
						|
  <button [attr.disabled]="isUnchanged">Disabled</button>
 | 
						|
 | 
						|
  <button [attr.disabled]="!isUnchanged">Disabled as well</button>
 | 
						|
 | 
						|
  <!-- can't remove it with [attr.disabled] either -->
 | 
						|
  <button disabled [attr.disabled]>Still disabled</button>
 | 
						|
 | 
						|
  <!-- we'd have to remove it with property binding -->
 | 
						|
  <button disabled [disabled]="false">Enabled (but inert)</button>
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- class binding -->
 | 
						|
<hr><h2 id="class-binding">Class Binding</h2>
 | 
						|
 | 
						|
<!-- #docregion class-binding-1 -->
 | 
						|
<!-- standard class attribute setting  -->
 | 
						|
<div class="bad curly special">Bad curly special</div>
 | 
						|
<!-- #enddocregion class-binding-1 -->
 | 
						|
 | 
						|
<!-- #docregion class-binding-2 -->
 | 
						|
<!-- reset/override all class names with a binding  -->
 | 
						|
<div class="bad curly special"
 | 
						|
     [class]="badCurly">Bad curly</div>
 | 
						|
     <!-- Doesn't work, due to github.com/angular/angular/issues/6901 -->
 | 
						|
<!-- #enddocregion class-binding-2 -->
 | 
						|
 | 
						|
<!-- #docregion class-binding-3 -->
 | 
						|
<!-- #docregion class-binding-3a -->
 | 
						|
<!-- toggle the "special" class on/off with a property -->
 | 
						|
<div [class.special]="isSpecial">The class binding is special</div>
 | 
						|
<!-- #enddocregion class-binding-3a -->
 | 
						|
 | 
						|
<!-- binding to `class.special` trumps the class attribute -->
 | 
						|
<div class="special"
 | 
						|
     [class.special]="!isSpecial">This one is not so special</div>
 | 
						|
<!-- #enddocregion class-binding-3 -->
 | 
						|
 | 
						|
<div bind-class.special="isSpecial">This class binding is special too</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!--style binding -->
 | 
						|
<hr><h2 id="style-binding">Style Binding</h2>
 | 
						|
 | 
						|
<!-- #docregion style-binding-1 -->
 | 
						|
<button [style.color] = "isSpecial ? 'red': 'green'">Red</button>
 | 
						|
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
 | 
						|
<!-- #enddocregion style-binding-1 -->
 | 
						|
 | 
						|
<!-- #docregion style-binding-2 -->
 | 
						|
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
 | 
						|
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
 | 
						|
<!-- #enddocregion style-binding-2 -->
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- event binding -->
 | 
						|
<hr><h2 id="event-binding">Event Binding</h2>
 | 
						|
 | 
						|
<!-- #docregion event-binding-1 -->
 | 
						|
<button (click)="onSave()">Save</button>
 | 
						|
<!-- #enddocregion event-binding-1 -->
 | 
						|
 | 
						|
<!-- #docregion event-binding-2 -->
 | 
						|
<button on-click="onSave()">On Save</button>
 | 
						|
<!-- #enddocregion event-binding-2 -->
 | 
						|
 | 
						|
<div>
 | 
						|
<!-- #docregion event-binding-3 -->
 | 
						|
<!-- `myClick` is an event on the custom `MyClickDirective` -->
 | 
						|
<!-- #docregion my-click -->
 | 
						|
<div (myClick)="clickMessage=$event">click with myClick</div>
 | 
						|
<!-- #enddocregion my-click -->
 | 
						|
<!-- #enddocregion event-binding-3 -->
 | 
						|
{{clickMessage}}
 | 
						|
</div>
 | 
						|
 | 
						|
 | 
						|
<!-- binding to a nested component -->
 | 
						|
<!-- #docregion event-binding-to-component -->
 | 
						|
<hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></hero-detail>
 | 
						|
<!-- #enddocregion event-binding-to-component -->
 | 
						|
<br>
 | 
						|
 | 
						|
<big-hero-detail
 | 
						|
    (deleteRequest)="deleteHero($event)"
 | 
						|
    [hero]="currentHero">
 | 
						|
</big-hero-detail>
 | 
						|
 | 
						|
<!-- #docregion event-binding-bubbling -->
 | 
						|
<div class="parent-div" (click)="onClickMe($event)">Click me
 | 
						|
  <div class="child-div">Click me too!</div>
 | 
						|
</div>
 | 
						|
<!-- #enddocregion event-binding-bubbling -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- #docregion event-binding-no-propagation -->
 | 
						|
<!-- Will save only once -->
 | 
						|
<div (click)="onSave()">
 | 
						|
  <button (click)="onSave()">Save, no propagation</button>
 | 
						|
</div>
 | 
						|
<!-- #enddocregion event-binding-no-propagation -->
 | 
						|
<br><br>
 | 
						|
<!-- #docregion event-binding-propagation -->
 | 
						|
<!-- Will save twice -->
 | 
						|
<div (click)="onSave()">
 | 
						|
  <button (click)="onSave() || true">Save w/ propagation</button>
 | 
						|
</div>
 | 
						|
<!-- #enddocregion event-binding-propagation -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- Two way data binding unwound;
 | 
						|
    passing the changed display value to the event handler via `$event` -->
 | 
						|
<hr><h2 id="ngModel">NgModel (two-way) Binding</h2>
 | 
						|
 | 
						|
<h3>Result: {{currentHero.firstName}}</h3>
 | 
						|
 | 
						|
<!-- #docregion without-NgModel -->
 | 
						|
<input [value]="currentHero.firstName"
 | 
						|
       (input)="currentHero.firstName=$event.target.value" >
 | 
						|
<!-- #enddocregion without-NgModel -->
 | 
						|
without NgModel
 | 
						|
<br>
 | 
						|
<!-- #docregion NgModel-1 -->
 | 
						|
<input [(ngModel)]="currentHero.firstName">
 | 
						|
<!-- #enddocregion NgModel-1 -->
 | 
						|
[(ngModel)]
 | 
						|
<br>
 | 
						|
<!-- #docregion NgModel-2 -->
 | 
						|
<input bindon-ngModel="currentHero.firstName">
 | 
						|
<!-- #enddocregion NgModel-2 -->
 | 
						|
bindon-ngModel
 | 
						|
<br>
 | 
						|
<!-- #docregion NgModel-3 -->
 | 
						|
<input
 | 
						|
    [ngModel]="currentHero.firstName"
 | 
						|
    (ngModelChange)="currentHero.firstName=$event">
 | 
						|
<!-- #enddocregion NgModel-3 -->
 | 
						|
(ngModelChange) = "...firstName=$event"
 | 
						|
<br>
 | 
						|
<!-- #docregion NgModel-4 -->
 | 
						|
<input
 | 
						|
    [ngModel]="currentHero.firstName"
 | 
						|
    (ngModelChange)="setUpperCaseFirstName($event)">
 | 
						|
<!-- #enddocregion NgModel-4 -->
 | 
						|
(ngModelChange) = "setUpperCaseFirstName($event)"
 | 
						|
<br>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- NgClass binding -->
 | 
						|
<hr><h2 id="ngClass">NgClass Binding</h2>
 | 
						|
 | 
						|
<p>setClasses returns {{setClasses() | json}}</p>
 | 
						|
<!-- #docregion NgClass-1 -->
 | 
						|
<div [ngClass]="setClasses()">This div is saveable and special</div>
 | 
						|
<!-- #enddocregion NgClass-1 -->
 | 
						|
<div [ngClass]="setClasses()" #classDiv>
 | 
						|
  After setClasses(), the classes are "{{classDiv.className}}"
 | 
						|
</div>
 | 
						|
 | 
						|
<!-- not used in chapter -->
 | 
						|
 | 
						|
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
 | 
						|
 | 
						|
<div class="bad curly special">Bad curly special</div>
 | 
						|
<div [ngClass]="{bad:false, curly:true, special:true}">Curly special</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- NgStyle binding -->
 | 
						|
<hr><h2>NgStyle Binding</h2>
 | 
						|
 | 
						|
<!-- #docregion NgStyle-1 -->
 | 
						|
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
 | 
						|
  This div is x-large.
 | 
						|
</div>
 | 
						|
<!-- #enddocregion NgStyle-1 -->
 | 
						|
 | 
						|
<h3>Use setStyles() - CSS property names</h3>
 | 
						|
<p>setStyles returns {{setStyles()}}.</p>
 | 
						|
<!-- #docregion NgStyle-2 -->
 | 
						|
<div [ngStyle]="setStyles()">
 | 
						|
  This div is italic, normal weight, and extra large (24px).
 | 
						|
</div>
 | 
						|
<!-- #enddocregion NgStyle-2 -->
 | 
						|
<p>After setStyles(), the DOM confirms that the styles are
 | 
						|
  <span [ngStyle]="setStyles()" #styleDiv>
 | 
						|
    {{getStyles(styleDiv)}}
 | 
						|
  </span>.
 | 
						|
</p>
 | 
						|
 | 
						|
<!-- not used in chapter -->
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- NgIf binding -->
 | 
						|
<hr><h2 id="ngIf">NgIf Binding</h2>
 | 
						|
 | 
						|
<!-- #docregion NgIf-1 -->
 | 
						|
<div *ngIf="currentHero != null">Hello, {{currentHero.firstName}}</div>
 | 
						|
<!-- #enddocregion NgIf-1 -->
 | 
						|
 | 
						|
<!-- #docregion NgIf-2 -->
 | 
						|
<!-- not displayed because nullHero is false.
 | 
						|
    `nullHero.firstName` never has a chance to fail -->
 | 
						|
<div *ngIf="nullHero != null">Hello, {{nullHero.firstName}}</div>
 | 
						|
 | 
						|
<!-- Hero Detail is not in the DOM because isActive is false-->
 | 
						|
<hero-detail *ngIf="isActive"></hero-detail>
 | 
						|
<!-- #enddocregion NgIf-2 -->
 | 
						|
 | 
						|
<!-- NgIf binding with template (no *) -->
 | 
						|
 | 
						|
<template [ngIf]="currentHero != null">Add {{currentHero.firstName}} with template</template>
 | 
						|
 | 
						|
<!-- Does not show because isActive is false! -->
 | 
						|
<div>Hero Detail removed from DOM (via template) because isActive is false</div>
 | 
						|
<template [ngIf]="isActive">
 | 
						|
  <hero-detail></hero-detail>
 | 
						|
</template>
 | 
						|
 | 
						|
<!-- #docregion NgIf-3 -->
 | 
						|
<!-- isSpecial is true -->
 | 
						|
<div [class.hidden]="!isSpecial">Show with class</div>
 | 
						|
<div [class.hidden]="isSpecial">Hide with class</div>
 | 
						|
 | 
						|
<!-- HeroDetail is in the DOM but hidden -->
 | 
						|
<hero-detail [class.hidden]="isSpecial"></hero-detail>
 | 
						|
 | 
						|
<div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div>
 | 
						|
<div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div>
 | 
						|
<!-- #enddocregion NgIf-3 -->
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- NgSwitch binding -->
 | 
						|
<hr><h2 id="ngSwitch">NgSwitch Binding</h2>
 | 
						|
 | 
						|
<fieldset #toePicker (click)="toeChooser(toePicker)" >
 | 
						|
  <input type="radio" name="toes" value="Eenie">Eenie
 | 
						|
  <input type="radio" name="toes" value="Meanie">Meanie
 | 
						|
  <input type="radio" name="toes" value="Miney">Miney
 | 
						|
  <input type="radio" name="toes" value="Moe">Moe
 | 
						|
  <input type="radio" name="toes" value="???">???
 | 
						|
</fieldset>
 | 
						|
 | 
						|
<div class="toe">
 | 
						|
    <div *ngIf="toeChoice == null">Pick a toe</div>
 | 
						|
    <div *ngIf="toeChoice != null">
 | 
						|
      You picked ...
 | 
						|
      <!-- #docregion NgSwitch, NgSwitch-expanded -->
 | 
						|
      <span [ngSwitch]="toeChoice">
 | 
						|
      <!-- #enddocregion NgSwitch -->
 | 
						|
 | 
						|
        <!-- with *NgSwitch -->
 | 
						|
        <!-- #docregion NgSwitch -->
 | 
						|
        <span *ngSwitchWhen="'Eenie'">Eenie</span>
 | 
						|
        <span *ngSwitchWhen="'Meanie'">Meanie</span>
 | 
						|
        <span *ngSwitchWhen="'Miney'">Miney</span>
 | 
						|
        <span *ngSwitchWhen="'Moe'">Moe</span>
 | 
						|
        <span *ngSwitchDefault>other</span>
 | 
						|
        <!-- #enddocregion NgSwitch -->
 | 
						|
 | 
						|
        <!-- with <template> -->
 | 
						|
        <template ngSwitchWhen="Eenie"><span>Eenie</span></template>
 | 
						|
        <template ngSwitchWhen="Meanie"><span>Meanie</span></template>
 | 
						|
        <template ngSwitchWhen="Miney"><span>Miney</span></template>
 | 
						|
        <template ngSwitchWhen="Moe"><span>Moe</span></template>
 | 
						|
        <template ngSwitchDefault><span>other</span></template>
 | 
						|
 | 
						|
      <!-- #docregion NgSwitch -->
 | 
						|
      </span>
 | 
						|
      <!-- #enddocregion NgSwitch, NgSwitch-expanded -->
 | 
						|
    </div>
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- NgFor binding -->
 | 
						|
<hr><h2 id="ngFor">NgFor Binding</h2>
 | 
						|
 | 
						|
<div class="box">
 | 
						|
  <!-- #docregion NgFor-1 -->
 | 
						|
  <div *ngFor="#hero of heroes">{{hero.fullName}}</div>
 | 
						|
  <!-- #enddocregion NgFor-1 -->
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
 | 
						|
<div class="box">
 | 
						|
  <!-- *ngFor w/ hero-detail Component -->
 | 
						|
  <!-- #docregion NgFor-2 -->
 | 
						|
  <hero-detail *ngFor="#hero of heroes" [hero]="hero"></hero-detail>
 | 
						|
  <!-- #enddocregion NgFor-2 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<h4 id="ngFor-index">NgFor with index</h4>
 | 
						|
<p>with <i>semi-colon</i> separator</p>
 | 
						|
<div class="box">
 | 
						|
  <!-- #docregion NgFor-3 -->
 | 
						|
  <div *ngFor="#hero of heroes; #i=index">{{i + 1}} - {{hero.fullName}}</div>
 | 
						|
  <!-- #enddocregion NgFor-3 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<p>with <i>comma</i> separator</p>
 | 
						|
<div class="box">
 | 
						|
  <!-- Ex: "1 - Hercules Son of Zeus"" -->
 | 
						|
  <div *ngFor="#hero of heroes, #i=index">{{i + 1}} - {{hero.fullName}}</div>
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<h4 id="ngFor-trackBy">NgForTrackBy</h4>
 | 
						|
<button (click)="refreshHeroes()">Refresh heroes</button>
 | 
						|
<p>First hero: <input [(ngModel)]="heroes[0].firstName"></p>
 | 
						|
 | 
						|
<p><i>without</i> trackBy</p>
 | 
						|
<div #noTrackBy class="box">
 | 
						|
  <!-- #docregion NgForTrackBy-1 -->
 | 
						|
  <div *ngFor="#hero of heroes">({{hero.id}}) {{hero.fullName}}</div>
 | 
						|
  <!-- #enddocregion NgForTrackBy-1 -->
 | 
						|
</div>
 | 
						|
<div id="noTrackByCnt" *ngIf="heroesNoTrackByChangeCount != 0" style="background-color:bisque">
 | 
						|
  Hero DOM elements change #<span style="background-color:gold">{{heroesNoTrackByChangeCount}}</span> without trackBy
 | 
						|
</div>
 | 
						|
 | 
						|
<p>with trackBy and <i>semi-colon</i> separator</p>
 | 
						|
<div #withTrackBy class="box">
 | 
						|
  <!-- #docregion NgForTrackBy-2 -->
 | 
						|
  <div *ngFor="#hero of heroes; trackBy:trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>
 | 
						|
  <!-- #enddocregion NgForTrackBy-2 -->
 | 
						|
</div>
 | 
						|
<div id="withTrackByCnt" *ngIf="heroesWithTrackByChangeCount != 0" style="background-color:bisque">
 | 
						|
  Hero DOM elements change #<span style="background-color:gold">{{heroesWithTrackByChangeCount}}</span> with trackBy
 | 
						|
</div>
 | 
						|
 | 
						|
<p>with trackBy and <i>comma</i> separator</p>
 | 
						|
<div class="box">
 | 
						|
  <div *ngFor="#hero of heroes, trackBy:trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>
 | 
						|
</div>
 | 
						|
 | 
						|
<p>with trackBy and <i>space</i> separator</p>
 | 
						|
<div class="box">
 | 
						|
  <div *ngFor="#hero of heroes trackBy:trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>
 | 
						|
</div>
 | 
						|
 | 
						|
<p>with <i>*ngForTrackBy</i></p>
 | 
						|
<div class="box">
 | 
						|
  <!-- #docregion NgForTrackBy-2 -->
 | 
						|
  <div *ngFor="#hero of heroes" *ngForTrackBy="trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>
 | 
						|
  <!-- #enddocregion NgForTrackBy-2 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<p>with <i>generic</i> trackById function</p>
 | 
						|
<div class="box">
 | 
						|
  <!-- #docregion NgForTrackBy-3 -->
 | 
						|
  <div *ngFor="#hero of heroes" *ngForTrackBy="trackById">({{hero.id}}) {{hero.fullName}}</div>
 | 
						|
  <!-- #enddocregion NgForTrackBy-3 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- * and template -->
 | 
						|
<hr><h2 id="star-prefix">* prefix and <template></h2>
 | 
						|
 | 
						|
<h3>*ngIf expansion</h3>
 | 
						|
<p><i>*ngIf</i></p>
 | 
						|
<!-- #docregion Template-1 -->
 | 
						|
<hero-detail *ngIf="currentHero != null" [hero]="currentHero"></hero-detail>
 | 
						|
<!-- #enddocregion Template-1 -->
 | 
						|
 | 
						|
<p><i>expand to template = "..."</i></p>
 | 
						|
<!-- #docregion Template-2a -->
 | 
						|
<hero-detail template="ngIf:currentHero != null" [hero]="currentHero"></hero-detail>
 | 
						|
<!-- #enddocregion Template-2a -->
 | 
						|
 | 
						|
<p><i>expand to <template></i></p>
 | 
						|
<!-- #docregion Template-2 -->
 | 
						|
<template [ngIf]="currentHero != null">
 | 
						|
    <hero-detail [hero]="currentHero"></hero-detail>
 | 
						|
</template>
 | 
						|
<!-- #enddocregion Template-2 -->
 | 
						|
 | 
						|
<h3>*ngFor expansion</h3>
 | 
						|
<p><i>*ngFor</i></p>
 | 
						|
  <!-- *ngFor w/ hero-detail Component -->
 | 
						|
  <!-- #docregion Template-3a -->
 | 
						|
  <hero-detail *ngFor="#hero of heroes; trackBy:trackByHeroes" [hero]="hero"></hero-detail>
 | 
						|
  <!-- #enddocregion Template-3a -->
 | 
						|
 | 
						|
<p><i>expand to template = "..."</i></p>
 | 
						|
<div class="box">
 | 
						|
  <!-- *ngFor w/ hero-detail Component and a template "attribute" directive -->
 | 
						|
  <!-- #docregion Template-3 -->
 | 
						|
  <hero-detail template="ngFor #hero of heroes; trackBy:trackByHeroes" [hero]="hero"></hero-detail>
 | 
						|
  <!-- #enddocregion Template-3 -->
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
 | 
						|
<p><i>expand to <template></i></p>
 | 
						|
<div class="box">
 | 
						|
  <!-- ngFor w/ hero-detail Component inside a template element -->
 | 
						|
  <!-- #docregion Template-4 -->
 | 
						|
  <template ngFor #hero [ngForOf]="heroes" [ngForTrackBy]="trackByHeroes">
 | 
						|
      <hero-detail [hero]="hero"></hero-detail>
 | 
						|
  </template>
 | 
						|
  <!-- #enddocregion Template-4 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- template local variable -->
 | 
						|
<hr><h2 id="local-vars">Template local variables</h2>
 | 
						|
 | 
						|
<!-- #docregion var-phone -->
 | 
						|
<!-- phone refers to the input element; pass its `value` to an event handler -->
 | 
						|
<input #phone placeholder="phone number">
 | 
						|
<button (click)="callPhone(phone.value)">Call</button>
 | 
						|
 | 
						|
<!-- fax refers to the input element; pass its `value` to an event handler -->
 | 
						|
<input var-fax placeholder="phone number">
 | 
						|
<button (click)="callFax(fax.value)">Fax</button>
 | 
						|
<!-- #enddocregion var-phone -->
 | 
						|
 | 
						|
<h4>Example Form</h4>
 | 
						|
<!-- #docregion var-form -->
 | 
						|
<!-- #docregion var-form-a -->
 | 
						|
<form (ngSubmit)="onSubmit(theForm)" #theForm="ngForm">
 | 
						|
<!-- #enddocregion var-form-a -->
 | 
						|
  <div class="form-group">
 | 
						|
    <label for="name">Name</label>
 | 
						|
    <input id="name" class="form-control" required ngControl="firstName"
 | 
						|
        [(ngModel)]="currentHero.firstName">
 | 
						|
  </div>
 | 
						|
  <!-- #docregion var-form-a -->
 | 
						|
  <button type="submit" [disabled]="!theForm.form.valid">Submit</button>
 | 
						|
</form>
 | 
						|
<!-- #enddocregion var-form-a -->
 | 
						|
<!-- #enddocregion var-form -->
 | 
						|
<br><br>
 | 
						|
 | 
						|
<!-- btn refers to the button element; show its disabled state -->
 | 
						|
<button #btn disabled [textContent]="'disabled by attribute: ' + btn.disabled.toString()"></button>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- inputs and output -->
 | 
						|
<hr><h2 id="inputs-and-outputs">Inputs and Outputs</h2>
 | 
						|
 | 
						|
<!-- #docregion io-1 -->
 | 
						|
<img [src]="iconUrl"/>
 | 
						|
<button (click)="onSave()">Save</button>
 | 
						|
<!-- #enddocregion io-1 -->
 | 
						|
 | 
						|
<!-- #docregion io-2 -->
 | 
						|
<hero-detail [hero]="currentHero" (deleteRequest)="deleteHero($event)">
 | 
						|
</hero-detail>
 | 
						|
<!-- #enddocregion io-2 -->
 | 
						|
 | 
						|
<div (myClick)="clickMessage2=$event">myClick2</div>
 | 
						|
{{clickMessage2}}
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- Pipes -->
 | 
						|
<hr><h2 id="pipes">Pipes</h2>
 | 
						|
 | 
						|
<!-- #docregion pipes-1 -->
 | 
						|
<!-- Force title to uppercase -->
 | 
						|
<div>{{ title | uppercase }}</div>
 | 
						|
<!-- #enddocregion pipes-1 -->
 | 
						|
 | 
						|
<!-- #docregion pipes-2 -->
 | 
						|
<!-- Pipe chaining: force title to uppercase, then to lowercase -->
 | 
						|
<div>{{ title | uppercase | lowercase }}</div>
 | 
						|
<!-- #enddocregion pipes-2 -->
 | 
						|
 | 
						|
<!-- #docregion pipes-3 -->
 | 
						|
<!-- pipe with configuration argument => "February 25, 1970" -->
 | 
						|
<div>Birthdate: {{currentHero?.birthdate | date:'longDate'}}</div>
 | 
						|
<!-- #enddocregion pipes-3 -->
 | 
						|
 | 
						|
<!-- #docregion pipes-json -->
 | 
						|
<!-- We don't suggest using json for debugging; you'd probably use toString() instead.
 | 
						|
     Is there a good use for the json pipe in Dart? -->
 | 
						|
<!--<div>{{currentHero | json}}</div>-->
 | 
						|
<!-- #enddocregion pipes-json -->
 | 
						|
 | 
						|
<div>Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}</div>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- pipe price to USD and display the $ symbol -->
 | 
						|
  <label>Price: </label>{{product['price'] | currency:'$'}}
 | 
						|
</div>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
 | 
						|
<!-- Null values and the Elvis operator -->
 | 
						|
<hr><h2 id="elvis">Elvis <i>?.</i></h2>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion elvis-1 -->
 | 
						|
  The title is {{ title }}
 | 
						|
  <!-- #enddocregion elvis-1 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion elvis-2 -->
 | 
						|
  The current hero's name is {{currentHero?.firstName}}
 | 
						|
  <!-- #enddocregion elvis-2 -->
 | 
						|
</div>
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion elvis-3 -->
 | 
						|
  The current hero's name is {{currentHero.firstName}}
 | 
						|
  <!-- #enddocregion elvis-3 -->
 | 
						|
</div>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<!--
 | 
						|
The null hero's name is {{nullHero.firstName}}
 | 
						|
 | 
						|
  See console log:
 | 
						|
  EXCEPTION: The null object does not have a getter 'firstName'.
 | 
						|
-->
 | 
						|
 | 
						|
<!-- #docregion elvis-4 -->
 | 
						|
<!--No hero, div not displayed, no error -->
 | 
						|
<div *ngIf="nullHero != null">The null hero's name is {{nullHero.firstName}}</div>
 | 
						|
<!-- #enddocregion elvis-4 -->
 | 
						|
 | 
						|
<!-- skip docregion elvis-5 -->
 | 
						|
 | 
						|
<div>
 | 
						|
  <!-- #docregion elvis-6 -->
 | 
						|
  <!-- No hero, no problem! -->
 | 
						|
  The null hero's name is {{nullHero?.firstName}}
 | 
						|
  <!-- #enddocregion elvis-6 -->
 | 
						|
</div>
 | 
						|
 | 
						|
 | 
						|
<!-- Todo: discuss this in the Style binding section -->
 | 
						|
<!-- enums in bindings -->
 | 
						|
<!--
 | 
						|
<hr><h2 id="enums">Enums in binding</h2>
 | 
						|
 | 
						|
<p>The current color number is {{color}}</p>
 | 
						|
<p><button [style.color]="color.toString()" (click)="colorToggle()">Enum Toggle</button>
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 | 
						|
-->
 | 
						|
 | 
						|
<!-- #docregion my-first-app -->
 | 
						|
<h3>My First Angular Application</h3>
 | 
						|
<!-- #enddocregion my-first-app -->
 | 
						|
 | 
						|
<a class="to-toc" href="#toc">top</a>
 |