377 lines
9.8 KiB
HTML
377 lines
9.8 KiB
HTML
<!-- Interpolation and expressions</h1> -->
|
|
<h3>My First Angular Application</h3>
|
|
<h3>
|
|
{{title}}
|
|
<img src="{{heroImageUrl}}" style="height:30px">
|
|
</h3>
|
|
<p>My current hero is {{currentHero.firstName}}</p>
|
|
|
|
<div title="Hello {{currentHero.firstName}}">
|
|
Hey there, {{currentHero.firstName}}
|
|
</div>
|
|
|
|
<h3 [text-content]="'The title is '+title"></h3>
|
|
<h3>The title is {{title}}</h3>
|
|
<h3>The sum of 1 + 1 is not {{1+1+getVal()}}</h3>
|
|
<h3 id="3" #f>The element id is {{f.id}}</h3>
|
|
|
|
<hr>
|
|
<img src="{{heroImageUrl}}"/>
|
|
<img [src]="'' + heroImageUrl"/>
|
|
|
|
<h3>The title is {{title}}</h3>
|
|
<h3 [text-content]="'The title is '+title"></h3>
|
|
|
|
|
|
|
|
<!-- New Mental Model -->
|
|
<hr>
|
|
<div class="special">Mental Model</div>
|
|
|
|
<div class="special">
|
|
<!--<img src="http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png">-->
|
|
<img src="../../images/hero.png">
|
|
<button disabled>Save</button>
|
|
</div>
|
|
|
|
<div *ng-if="false">
|
|
<hero-detail></hero-detail>
|
|
</div>
|
|
|
|
<hr>
|
|
<!-- BAD: No Mixed Case
|
|
<h3 [textContent]="title"></h3>
|
|
-->
|
|
<!-- property over attribute -->
|
|
<!-- examine the following <img> tag in the browser tools -->
|
|
<img src="../../images/ng-logo.png"
|
|
[src]="heroImageUrl">
|
|
<hr>
|
|
<h3 [text-content]="title"></h3>
|
|
<hr/>
|
|
<img [src]="iconUrl"/>
|
|
<img bind-src="heroImageUrl"/>
|
|
<img [attr.src]="villainImageUrl"/>
|
|
|
|
|
|
|
|
<!-- buttons -->
|
|
<hr>
|
|
|
|
<button>Enabled</button>
|
|
<button disabled>Disabled</button>
|
|
<button disabled=false>Still disabled</button>
|
|
<hr>
|
|
<button disabled>disabled by attribute</button>
|
|
<button [disabled]="isUnchanged">disabled by property binding</button>
|
|
|
|
<button bind-disabled="isUnchanged" on-click="onSave($event)">Disabled Cancel</button>
|
|
<button [disabled]="!canSave" (click)="onSave($event)">Enabled Save</button>
|
|
<hr>
|
|
|
|
|
|
|
|
|
|
<!-- event binding -->
|
|
|
|
<button (click)="onSave()">Save</button>
|
|
<button on-click="onSave()">On Save</button>
|
|
<button (click)="onSave() || true">Save w/ propagation</button>
|
|
|
|
<button (click)="onClickMe()">Click me!</button>
|
|
|
|
<div class="parent-div" (click)="onClickMe($event)">Click me
|
|
<div class="child-div">Click me too!</div>
|
|
</div>
|
|
|
|
<click-me></click-me>
|
|
|
|
<h4>keyup loop-back component</h4>
|
|
<loop-back></loop-back>
|
|
|
|
<key-up></key-up>
|
|
|
|
<key-up2></key-up2>
|
|
|
|
<key-up3></key-up3>
|
|
<br>
|
|
<div class="box">
|
|
<little-tour></little-tour>
|
|
</div>
|
|
|
|
<!-- attribute binding -->
|
|
<hr>
|
|
<!-- any value creates the disabled attribute -->
|
|
<button [attr.disabled]="isUnchanged">Disabled</button>
|
|
<button [attr.disabled]="isUnchanged">Disabled as well</button>
|
|
|
|
<!-- lack of expression removes the attribute -->
|
|
<button disabled [attr.disabled]>Enabled</button>
|
|
|
|
<!-- create and set an aria attribute for assistive technology -->
|
|
<button [attr.aria-label]="actionName">{{actionName}} with Aria</button>
|
|
|
|
<!-- create and set a span attribute -->
|
|
<table border=1>
|
|
<tr><td>One</td><td>Two</td></tr>
|
|
|
|
<!-- ERROR: There is no `colspan` property to set!
|
|
<tr><td colspan="{{1+1}}">Three-Four</td></tr>
|
|
-->
|
|
|
|
<!-- expression calculates colspan=2 -->
|
|
<tr><td [attr.colspan]="1 + 1">Five-Six</td></tr>
|
|
</table>
|
|
<hr>
|
|
|
|
|
|
|
|
|
|
<!-- class binding -->
|
|
<hr>
|
|
<div class="special">The class is special</div>
|
|
<div [class]="'special'">The class is special</div>
|
|
<!-- toggle the "special" class on and ohf -->
|
|
<div [class.special]="isSpecial">The class binding is special</div>
|
|
|
|
<div class="special" [class.special]="!isSpecial">This one is not so special</div>
|
|
|
|
<div bind-class.special="isSpecial">This class binding is special too</div>
|
|
|
|
|
|
|
|
|
|
<!--style binding -->
|
|
<hr>
|
|
<button [style.color] = "isSpecial ? 'red' : 'green'">Red</button>
|
|
<button [style.background-color]="canSave ?'cyan' : 'grey'" >Save</button>
|
|
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
|
|
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
|
|
|
|
|
|
|
|
|
|
<!-- binding to a nested component -->
|
|
<hr>
|
|
<div>{{currentHero?.firstName}}</div>
|
|
|
|
<hero-detail [hero]="currentHero" (deleted)="onDeleted($event)"></hero-detail>
|
|
|
|
|
|
|
|
<!-- Two way data binding unwound;
|
|
passing the changed display value to the event handler via `$event` -->
|
|
<hr>
|
|
<input [value]="currentHero.firstName"
|
|
(input)="currentHero.firstName=$event.target.value" >
|
|
<br>
|
|
<input [(ng-model)]="currentHero.firstName">
|
|
<br>
|
|
<input
|
|
[ng-model]="currentHero.firstName"
|
|
(ng-model-change)="currentHero.firstName=$event">
|
|
<br>
|
|
<input
|
|
[ng-model]="currentHero.lastName"
|
|
(ng-model-change)="setLastName($event)">
|
|
<br>
|
|
|
|
<div>{{currentHero.fullName}}</div>
|
|
|
|
|
|
|
|
|
|
<!-- NgClass binding -->
|
|
<hr>
|
|
<div [ng-class]="isSpecial ? special : ''">This div is special</div>
|
|
|
|
<div [ng-class]="setClasses()">This div is saveable and special</div>
|
|
<div [ng-class]="setClasses()" #class-div>
|
|
After setClasses(), the classes are "{{classDiv.className}}"
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- NgStyle binding -->
|
|
<hr>
|
|
<div [style.font-size]="isSpecial ? 'larger' : 'smaller'" >This div is larger</div>
|
|
|
|
<div [ng-style]="setStyles()">This div is italic, normal weight, and larger</div>
|
|
<div [ng-style]="setStyles()" #class-div>
|
|
After setStyles(), the styles are "{{getStyles(classDiv)}}"
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- NgIf binding -->
|
|
<hr>
|
|
<div><b>NgIf Binding</b></div>
|
|
|
|
<div *ng-if="currentHero">Add {{currentHero.firstName}}</div>
|
|
<div *ng-if="nullHero">Remove {{nullHero.firstName}}</div>
|
|
|
|
<div>Hero Detail removed from DOM because isActive is false</div>
|
|
<hero-detail *ng-if="isActive" [hero]="currentHero"></hero-detail>
|
|
|
|
|
|
|
|
|
|
<!-- NgIf binding with template (no *) -->
|
|
|
|
<template [ng-if]="currentHero">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 [ng-if]="isActive">
|
|
<hero-detail [hero]="currentHero"></hero-detail>
|
|
</template>
|
|
|
|
<!-- isSpecial is true -->
|
|
<div [class.hidden]="!isSpecial">Show with class</div>
|
|
<div [class.hidden]="isSpecial">Hide with class</div>
|
|
<hero-detail [class.hidden]="isSpecial" [hero]="currentHero"></hero-detail>
|
|
|
|
<div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div>
|
|
<div [style.display]="isSpecial ? 'none' : 'block'">Hide with style</div>
|
|
|
|
|
|
|
|
|
|
<!-- NgSwitch binding -->
|
|
<hr>
|
|
<div><b>NgSwitch Binding</b></div>
|
|
<fieldset #toe-picker (click)="null" >
|
|
<input type="radio" name="toes" value="Eenie">Eenie
|
|
<input type="radio" name="toes" checked 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">You picked
|
|
<span [ng-switch]="toeChoice(toePicker)">
|
|
<template [ng-switch-when]="'Eenie'">Eenie</template>
|
|
<template [ng-switch-when]="'Meanie'">Meanie</template>
|
|
<template [ng-switch-when]="'Miney'">Miney</template>
|
|
<template [ng-switch-when]="'Moe'">Moe</template>
|
|
<template ng-switch-default>Other</template>
|
|
</span>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- NgFor binding -->
|
|
<hr>
|
|
<div><b>NgFor Binding</b></div>
|
|
<br>
|
|
|
|
<div class="box">
|
|
<!-- *ng-for of div w/ interpolation -->
|
|
<div *ng-for="#hero of heroes">{{hero.fullName}}</div>
|
|
</div>
|
|
<br>
|
|
|
|
<div class="box">
|
|
<!-- *ng-for of div w/ interpolation -->
|
|
<!-- Ex: 1 - Hercules Son of Zeus -->
|
|
<div *ng-for="#hero of heroes, #i=index">{{i+1}} - {{hero.fullName}}</div>
|
|
</div>
|
|
<br>
|
|
|
|
<div class="box">
|
|
<!-- *ng-for w/ little-hero Component -->
|
|
<little-hero *ng-for="#hero of heroes" [hero]="hero"></little-hero>
|
|
</div>
|
|
<br>
|
|
|
|
<div class="box">
|
|
<!-- ng-for w/ little-hero Component and a template "attribute" directive -->
|
|
<little-hero template="ng-for #hero of heroes" [hero]="hero"></little-hero>
|
|
</div>
|
|
<br>
|
|
|
|
<div class="box">
|
|
<!-- ng-for w/ little-hero Component inside a template element -->
|
|
<template ng-for #hero [ng-for-of]="heroes">
|
|
<little-hero [hero]="hero"></little-hero>
|
|
</template>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Pipe operator -->
|
|
<hr>
|
|
<!-- Force title to uppercase -->
|
|
<div>{{ title | uppercase }}</div>
|
|
|
|
<!-- Pipe chaining: force title to uppercase, then to lowercase -->
|
|
<div>{{ title | uppercase | lowercase }}</div>
|
|
|
|
<!-- pipe with configuration argument -->
|
|
<div>Birthdate: {{currentHero?.birthdate | date:'longDate'}}</div>
|
|
|
|
<div>Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}</div>
|
|
|
|
|
|
<div>
|
|
<!-- pipe price to USD and display the $ symbol -->
|
|
<label>Price: </label>{{product.price | currency:'USD':true}}
|
|
</div>
|
|
|
|
|
|
<!-- Null values and the Elvis operator -->
|
|
<hr>
|
|
<div>The title is {{ title }}</div>
|
|
|
|
<div>The current hero's name is {{currentHero?.firstName}}</div>
|
|
|
|
<div>The current hero's name is {{currentHero.firstName}}</div>
|
|
|
|
<!--
|
|
<div>The null hero's name is {{nullHero.firstName}}</div>
|
|
|
|
See console log
|
|
TypeError: Cannot read property 'firstName' of null in [null]
|
|
-->
|
|
<!--No hero, div not displayed, no error -->
|
|
<div *ng-if="nullHero">The null hero's name is {{nullHero?.firstName}}</div>
|
|
|
|
<!--guard in the expression, no display, no error
|
|
[FAILS No short-circuiting of logical operators]
|
|
<div>The null hero's name is {{nullHero && nullHero.firstName}}</div>
|
|
-->
|
|
|
|
<!-- No hero, no problem! -->
|
|
<div>The null hero's name is {{nullHero?.firstName}}</div>
|
|
|
|
|
|
|
|
|
|
<!-- template local variable -->
|
|
<hr>
|
|
<h3>Template Driven Form</h3>
|
|
<form (ng-submit)="onSubmit(hf)" #hf="form">
|
|
<div class="form-group">
|
|
<label for="name">Name</label>
|
|
<input type="text" class="form-control" required
|
|
ng-control="firstName"
|
|
[(ng-model)]="currentHero.firstName">
|
|
</div>
|
|
<button type="submit" [disabled]="!hf.form.valid">Submit</button>
|
|
</form>
|
|
<hr>
|
|
|
|
|
|
<!-- btn refers to the button element; show its disabled state -->
|
|
<button #btn disabled [text-content]="'disabled by attribute: '+btn.disabled"></button>
|
|
|
|
<!-- 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>
|
|
|
|
<!-- ohficFax refers to the input element; pass its `value` to an event handler -->
|
|
<input var-ohfice-fax placeholder="phone number">
|
|
<button (click)="callFax(ohficeFax.value)">Fax</button>
|