2016-01-10 20:07:19 -05:00
|
|
|
//#docplaster
|
|
|
|
|
2016-02-06 20:18:26 -05:00
|
|
|
import {Component, AfterViewInit, ElementRef, OnInit, QueryList, ViewChildren} from 'angular2/core';
|
2015-12-08 14:22:15 -05:00
|
|
|
import {NgForm} from 'angular2/common';
|
2015-12-07 16:31:26 -05:00
|
|
|
|
|
|
|
import {Hero} from './hero';
|
|
|
|
import {HeroDetailComponent, BigHeroDetailComponent} from './hero-detail.component';
|
|
|
|
import {MyClickDirective, MyClickDirective2} from './my-click.directive';
|
|
|
|
|
|
|
|
// Alerter fn: monkey patch during test
|
|
|
|
export function alerter(msg?:string) {
|
|
|
|
window.alert(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
export enum Color {Red, Green, Blue};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Giant grab bag of stuff to drive the chapter
|
|
|
|
*/
|
|
|
|
@Component({
|
|
|
|
selector: 'my-app',
|
|
|
|
templateUrl: 'app/app.component.html',
|
|
|
|
directives: [
|
|
|
|
HeroDetailComponent, BigHeroDetailComponent,
|
|
|
|
MyClickDirective, MyClickDirective2
|
|
|
|
]
|
|
|
|
})
|
2016-02-06 20:18:26 -05:00
|
|
|
export class AppComponent implements AfterViewInit, OnInit {
|
|
|
|
|
|
|
|
ngOnInit(){
|
|
|
|
this.refreshHeroes();
|
|
|
|
}
|
|
|
|
|
|
|
|
ngAfterViewInit() {
|
|
|
|
this._detectNgForTrackByEffects();
|
|
|
|
}
|
2015-12-07 16:31:26 -05:00
|
|
|
|
|
|
|
actionName = 'Go for it';
|
|
|
|
alert = alerter;
|
2016-01-28 19:01:39 -05:00
|
|
|
badCurly = 'bad curly';
|
2016-02-17 13:59:14 -05:00
|
|
|
classes = 'special';
|
|
|
|
|
2015-12-07 16:31:26 -05:00
|
|
|
callFax(value:string) {this.alert(`Faxing ${value} ...`)}
|
|
|
|
callPhone(value:string) {this.alert(`Calling ${value} ...`)}
|
|
|
|
canSave = true;
|
|
|
|
|
|
|
|
Color = Color;
|
|
|
|
color = Color.Red;
|
|
|
|
colorToggle() {this.color = (this.color === Color.Red)? Color.Blue : Color.Red}
|
|
|
|
|
|
|
|
currentHero = Hero.MockHeroes[0];
|
|
|
|
|
2016-02-17 13:59:14 -05:00
|
|
|
deleteHero(hero:Hero){
|
|
|
|
this.alert('Deleted hero: '+ (hero && hero.firstName))
|
|
|
|
}
|
|
|
|
|
2016-01-10 20:07:19 -05:00
|
|
|
// DevMode memoization fields
|
|
|
|
private _priorClasses:{};
|
|
|
|
private _priorStyles:{};
|
|
|
|
private _priorStyles2:{};
|
|
|
|
|
2015-12-07 16:31:26 -05:00
|
|
|
getStyles(el:Element){
|
|
|
|
let styles = window.getComputedStyle(el);
|
|
|
|
let showStyles = {};
|
|
|
|
for (var p in this.setStyles()){
|
|
|
|
showStyles[p] = styles[p];
|
|
|
|
}
|
|
|
|
return JSON.stringify(showStyles);
|
|
|
|
}
|
|
|
|
|
|
|
|
getVal() {return this.val};
|
|
|
|
|
2016-02-06 20:18:26 -05:00
|
|
|
heroes:Hero[];
|
2015-12-07 16:31:26 -05:00
|
|
|
|
|
|
|
// heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
|
|
|
|
// Public Domain terms of use: http://www.wpclipart.com/terms.html
|
|
|
|
heroImageUrl = 'images/hero.png';
|
|
|
|
|
|
|
|
//iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png';
|
|
|
|
iconUrl = 'images/ng-logo.png';
|
|
|
|
isActive = false;
|
|
|
|
isSpecial = true;
|
|
|
|
isUnchanged = true;
|
|
|
|
|
|
|
|
nullHero:Hero = null; // or undefined
|
|
|
|
|
|
|
|
onCancel(event:KeyboardEvent){
|
|
|
|
let evtMsg = event ? ' Event target is '+ (<HTMLElement>event.target).innerHTML : '';
|
|
|
|
this.alert('Canceled.'+evtMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
onClickMe(event:KeyboardEvent){
|
|
|
|
let evtMsg = event ? ' Event target class is '+ (<HTMLElement>event.target).className : '';
|
|
|
|
this.alert('Click me.'+evtMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
onSave(event:KeyboardEvent){
|
|
|
|
let evtMsg = event ? ' Event target is '+ (<HTMLElement>event.target).innerText : '';
|
|
|
|
this.alert('Saved.'+evtMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
onSubmit(form:NgForm){
|
|
|
|
let evtMsg = form.valid ?
|
|
|
|
' Form value is '+ JSON.stringify(form.value) :
|
|
|
|
' Form is invalid';
|
|
|
|
this.alert('Form submitted.'+evtMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
product = {
|
|
|
|
name: 'frimfram',
|
|
|
|
price: 42
|
|
|
|
};
|
|
|
|
|
2016-02-06 20:18:26 -05:00
|
|
|
// #docregion refresh-heroes
|
|
|
|
// update this.heroes with fresh set of cloned heroes
|
|
|
|
refreshHeroes() {
|
|
|
|
this.heroes = Hero.MockHeroes.map(hero => Hero.clone(hero));
|
|
|
|
}
|
|
|
|
// #enddocregion refresh-heroes
|
|
|
|
|
|
|
|
// #docregion same-as-it-ever-was
|
|
|
|
private _samenessCount = 5;
|
|
|
|
moreOfTheSame() {this._samenessCount++;};
|
|
|
|
get sameAsItEverWas() {
|
|
|
|
var result:string[] = Array(this._samenessCount);
|
|
|
|
for (var i=result.length; i-- > 0;){result[i]='same as it ever was ...'}
|
|
|
|
return result;
|
|
|
|
// return [1,2,3,4,5].map(id => {
|
|
|
|
// return {id:id, text: 'same as it ever was ...'};
|
|
|
|
// });
|
|
|
|
}
|
|
|
|
// #enddocregion same-as-it-ever-was
|
|
|
|
|
2015-12-07 16:31:26 -05:00
|
|
|
setUpperCaseFirstName(firstName:string){
|
|
|
|
//console.log(firstName);
|
|
|
|
this.currentHero.firstName = firstName.toUpperCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
// #docregion setClasses
|
|
|
|
setClasses() {
|
2016-01-10 20:07:19 -05:00
|
|
|
let classes = {
|
2015-12-07 16:31:26 -05:00
|
|
|
saveable: this.canSave, // true
|
|
|
|
modified: !this.isUnchanged, // false
|
|
|
|
special: this.isSpecial, // true
|
|
|
|
}
|
2016-01-10 20:07:19 -05:00
|
|
|
// #enddocregion setClasses
|
|
|
|
// compensate for DevMode (sigh)
|
|
|
|
if (JSON.stringify(classes) === JSON.stringify(this._priorClasses)){
|
|
|
|
return this._priorClasses;
|
|
|
|
}
|
|
|
|
this._priorClasses = classes;
|
|
|
|
// #docregion setClasses
|
|
|
|
return classes;
|
2015-12-07 16:31:26 -05:00
|
|
|
}
|
|
|
|
// #enddocregion setClasses
|
|
|
|
|
2016-01-10 20:07:19 -05:00
|
|
|
|
2015-12-07 16:31:26 -05:00
|
|
|
// #docregion setStyles
|
|
|
|
setStyles() {
|
2016-01-10 20:07:19 -05:00
|
|
|
let styles = {
|
2015-12-14 01:29:37 -05:00
|
|
|
// CSS property names
|
2015-12-07 16:31:26 -05:00
|
|
|
'font-style': this.canSave ? 'italic' : 'normal', // italic
|
|
|
|
'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal
|
2016-01-28 19:01:39 -05:00
|
|
|
'font-size': this.isSpecial ? '24px' : '8px', // 24px
|
2015-12-07 16:31:26 -05:00
|
|
|
}
|
2016-01-10 20:07:19 -05:00
|
|
|
// #enddocregion setStyles
|
|
|
|
// compensate for DevMode (sigh)
|
|
|
|
if (JSON.stringify(styles) === JSON.stringify(this._priorStyles)){
|
|
|
|
return this._priorStyles;
|
|
|
|
}
|
|
|
|
this._priorStyles = styles;
|
|
|
|
// #docregion setStyles
|
|
|
|
return styles;
|
2015-12-07 16:31:26 -05:00
|
|
|
}
|
|
|
|
// #enddocregion setStyles
|
2016-01-10 20:07:19 -05:00
|
|
|
|
2015-12-14 01:29:37 -05:00
|
|
|
toeChoice = '';
|
|
|
|
toeChooser(picker:HTMLFieldSetElement){
|
2015-12-07 16:31:26 -05:00
|
|
|
let choices = picker.children;
|
|
|
|
for (let i=0; i<choices.length; i++){
|
|
|
|
var choice = <HTMLInputElement>choices[i];
|
2015-12-14 01:29:37 -05:00
|
|
|
if (choice.checked) {return this.toeChoice = choice.value}
|
2015-12-07 16:31:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-06 20:18:26 -05:00
|
|
|
title = 'Template Syntax';
|
|
|
|
|
|
|
|
// #docregion trackByHeroes
|
|
|
|
trackByHeroes(index: number, hero: Hero) { return hero.id; }
|
|
|
|
// #enddocregion trackByHeroes
|
|
|
|
|
|
|
|
// #docregion trackById
|
|
|
|
trackById(index: number, item: any): string { return item['id']; }
|
|
|
|
// #enddocregion trackById
|
|
|
|
|
2015-12-07 16:31:26 -05:00
|
|
|
val=2;
|
|
|
|
// villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png'
|
|
|
|
// Public Domain terms of use http://www.clker.com/disclaimer.html
|
|
|
|
villainImageUrl = 'images/villain.png'
|
|
|
|
|
2016-02-06 20:18:26 -05:00
|
|
|
|
|
|
|
//////// Detect effects of NgForTrackBy ///////////////
|
|
|
|
@ViewChildren('noTrackBy') childrenNoTrackBy:QueryList<ElementRef>;
|
|
|
|
@ViewChildren('withTrackBy') childrenWithTrackBy:QueryList<ElementRef>;
|
|
|
|
|
|
|
|
private _oldNoTrackBy:HTMLElement[];
|
|
|
|
private _oldWithTrackBy:HTMLElement[];
|
|
|
|
|
|
|
|
heroesNoTrackByChangeCount = 0;
|
|
|
|
heroesWithTrackByChangeCount = 0;
|
|
|
|
|
|
|
|
private _detectNgForTrackByEffects() {
|
|
|
|
this._oldNoTrackBy = toArray(this.childrenNoTrackBy);
|
|
|
|
this._oldWithTrackBy = toArray(this.childrenWithTrackBy);
|
|
|
|
|
|
|
|
this.childrenNoTrackBy.changes.subscribe((changes:any) => {
|
|
|
|
let newNoTrackBy = toArray(changes);
|
|
|
|
let isSame = this._oldNoTrackBy.every((v:any, i:number) => v === newNoTrackBy[i]);
|
|
|
|
if (!isSame) {
|
|
|
|
this._oldNoTrackBy = newNoTrackBy;
|
|
|
|
this.heroesNoTrackByChangeCount++;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
this.childrenWithTrackBy.changes.subscribe((changes:any) => {
|
|
|
|
let newWithTrackBy = toArray(changes);
|
|
|
|
let isSame = this._oldWithTrackBy.every((v:any, i:number) => v === newWithTrackBy[i]);
|
|
|
|
if (!isSame) {
|
|
|
|
this._oldWithTrackBy = newWithTrackBy;
|
|
|
|
this.heroesWithTrackByChangeCount++;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
///////////////////
|
|
|
|
|
2015-12-07 16:31:26 -05:00
|
|
|
}
|
2016-02-06 20:18:26 -05:00
|
|
|
|
|
|
|
// helper to convert viewChildren to an array of HTMLElements
|
|
|
|
function toArray(viewChildren:QueryList<ElementRef>) {
|
|
|
|
let result: HTMLElement[] = [];
|
|
|
|
let children = viewChildren.toArray()[0].nativeElement.children;
|
|
|
|
for (var i = 0; i < children.length; i++) { result.push(children[i]); }
|
|
|
|
return result;
|
|
|
|
}
|