docs(template-syntax): drive jade from sample

closes #456
This commit is contained in:
Ward Bell
2015-12-08 10:08:06 -08:00
parent b7897eef85
commit c33ee37144
15 changed files with 1409 additions and 1255 deletions
@@ -11,11 +11,11 @@
"author": "",
"license": "ISC",
"dependencies": {
"angular2": "2.0.0-alpha.46",
"systemjs": "0.19.2"
"angular2": "2.0.0-alpha.48",
"systemjs": "0.19.6"
},
"devDependencies": {
"live-server": "^0.8.1",
"typescript": "^1.6.2"
"typescript": "^1.7.2"
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,134 @@
import {Component, NgForm} from 'angular2/core';
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
]
})
export class AppComponent {
actionName = 'Go for it';
alert = alerter;
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];
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};
heroes = Hero.MockHeroes;
// 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)
}
onHeroDeleted(hero:Hero){
this.alert('Deleted hero: '+ (hero && hero.firstName))
}
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
};
setUpperCaseFirstName(firstName:string){
//console.log(firstName);
this.currentHero.firstName = firstName.toUpperCase();
}
// #docregion setClasses
setClasses() {
return {
saveable: this.canSave, // true
modified: !this.isUnchanged, // false
special: this.isSpecial, // true
}
}
// #enddocregion setClasses
// #docregion setStyles
setStyles() {
return {
'font-style': this.canSave ? 'italic' : 'normal', // italic
'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal
'font-size': this.isSpecial ? 'x-large': 'smaller', // larger
}
}
// #enddocregion setStyles
toeChoice(picker:HTMLFieldSetElement){
let choices = picker.children;
for (let i=0; i<choices.length; i++){
var choice = <HTMLInputElement>choices[i];
if (choice.checked) {return choice.value}
}
}
title = 'Template Syntax'
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'
}
File diff suppressed because it is too large Load Diff
@@ -1,299 +0,0 @@
// NOT EVERYTHING IS NEEDED BY TEMPLATE-SYNTAX CHAPTER
// Much left-over from support for "User Input" chapter such as
// ClickMeComponent,
// KeyUpComponent, KeyUpComponentV2, KeyUpComponentV3,
// LittleTour, LoopbackComponent,
// TODO: purge extraneous material
/// #docplaster
import {bootstrap, Component, CORE_DIRECTIVES,
Input, Output,
Directive,
ElementRef, EventEmitter,
NgForm, FORM_DIRECTIVES
} from 'angular2/angular2';
class Hero {
public id:number
constructor(
public firstName:string,
public lastName?:string,
public birthdate?:Date,
public url?:string,
public rate:number = 100) {
this.id = Hero.nextId++;
}
get fullName() {return `${this.firstName} ${this.lastName}`;}
static nextId = 1;
static MockHeroes = [
new Hero(
'Hercules',
'Son of Zeus',
new Date(1970, 1, 25),
'http://www.imdb.com/title/tt0065832/',
325),
new Hero('eenie', 'toe'),
new Hero('Meanie', 'Toe'),
new Hero('Miny', 'Toe'),
new Hero('Moe', 'Toe')
];
}
// for fun; not used (yet)
@Directive({selector: 'select'})
class DecoratorDirective {
constructor(el: ElementRef){
console.log(el)
}
}
@Component({
selector: 'hero-detail',
/*
inputs: ['hero'],
outputs: ['deleted'],
*/
template: `
<div style="border: 1px solid black; padding:3px">
<div><b>Hero Detail: {{hero?.fullName}}</b></div>
<div>First: {{hero?.firstName}}</div>
<div>Last: {{hero?.lastName}}</div>
<div>Birthdate: {{hero?.birthdate | date:'longDate'}}</div>
<div>Web: <a href="{{hero?.url}}" target="_blank">{{hero?.url}}</a></div>
<div>Rate/hr: {{hero?.rate | currency:'EUR'}}</div>
<button (click)="onDelete()">Delete</button>
</div>
`
})
class HeroDetailComponent {
@Input()
hero: Hero;
@Output()
deleted = new EventEmitter<Hero>();
onDelete() {
this.deleted.next(this.hero);
}
}
@Component({
selector: 'little-hero',
template: '<div>{{hero?.fullName}}</div>'
})
class LittleHeroComponent {
@Input()
hero: Hero;
}
@Component({
selector: 'click-me',
template: '<button (click)="onClickMe()">Click me</button>'
})
class ClickMeComponent {
onClickMe(){
alert('You are my hero!')
}
}
@Component({
selector: 'loop-back',
template: '<input #box (keyup)="0"> <p>{{box.value}}</p>'
})
class LoopbackComponent {
}
@Component({
selector: 'key-up',
template: `
<h4>Give me some keys!</h4>
<div><input (keyup)="onKey($event)"><div>
<div>{{values}}</div>
`
})
class KeyUpComponent {
values='';
onKey(event:KeyboardEvent) {
this.values += (<HTMLInputElement>event.target).value + ' | ';
}
}
@Component({
selector: 'key-up2',
template: `
<h4>Give me some more keys!</h4>
<div><input #box (keyup)="onKey(box.value)"><div>
<div>{{values}}</div>
`
})
class KeyUpComponentV2 {
values='';
onKey(value:string) {
this.values += value + ' | ';
}
}
@Component({
selector: 'key-up3',
template: `
<h4>Type away! Press [enter] when done.</h4>
<div><input #box (keyup.enter)="values=box.value"><div>
<div>{{values}}</div>
`
})
class KeyUpComponentV3 {
values='';
}
@Component({
selector: 'little-tour',
template: `
<h4>Little Tour of Heroes</h4>
<input #box
(keyup.enter)="addHero(box.value)"
(blur)="addHero(box.value)">
<button (click)=addHero(box.value)>Add</button>
<ul><li *ng-for="#hero of heroes">{{hero}}</li></ul>
`,
directives: [CORE_DIRECTIVES]
})
class LittleTour {
heroes=['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
addHero(newHero:string) {
if (newHero) {
this.heroes.push(newHero);
newHero = null; // clear the newHero textbox
}
}
}
bootstrap(LittleTour);
enum Color {Red, Green, Blue};
@Component({
selector: 'my-app',
templateUrl: 'app/app.html',
directives: [
CORE_DIRECTIVES, FORM_DIRECTIVES,
ClickMeComponent,
KeyUpComponent, KeyUpComponentV2, KeyUpComponentV3,
LittleTour, LoopbackComponent,
HeroDetailComponent, LittleHeroComponent
]
})
class AppComponent {
actionName = 'Go for it';
callFax(value:string) {alert(`Faxing ${value} ...`)}
callPhone(value:string) {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];
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};
heroes = Hero.MockHeroes;
//heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
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 : '';
alert('Canceled.'+evtMsg)
}
onClickMe(event:KeyboardEvent){
let evtMsg = event ? ' Event target class is '+ (<HTMLElement>event.target).className : '';
alert('Click me.'+evtMsg)
}
onDeleted(hero:Hero){
alert('Deleted hero: '+ (hero && hero.firstName))
}
onSave(event:KeyboardEvent){
let evtMsg = event ? ' Event target is '+ (<HTMLElement>event.target).innerText : '';
alert('Saved.'+evtMsg)
}
onSubmit(form:NgForm){
let evtMsg = form.valid ?
' Form value is '+ JSON.stringify(form.value) :
' Form is invalid';
alert('Form submitted.'+evtMsg)
}
product = {
name: 'frimfram',
price: 42
};
setLastName(lastName:string){
console.log(lastName);
this.currentHero.lastName = lastName;
}
setClasses() {
return {
saveable: this.canSave, // true
modified: !this.isUnchanged, // false
special: this.isSpecial, // true
}
}
setStyles() {
return {
'font-style': this.canSave ? 'italic' : 'normal', // italic
'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal
'font-size': this.isSpecial ? 'larger' : 'smaller', // larger
}
}
toeChoice(picker:HTMLFieldSetElement){
let choices = picker.children;
for (let i=0; i<choices.length; i++){
var choice = <HTMLInputElement>choices[i];
if (choice.checked) {return choice.value}
}
}
title = 'Template Syntax'
val=2;
// villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png'
villainImageUrl = 'images/villain.png'
}
bootstrap(AppComponent);
@@ -0,0 +1,3 @@
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
bootstrap(AppComponent);
@@ -0,0 +1,11 @@
// Useful for spying on an element
// for fun; not used (yet)
import {Directive, ElementRef} from 'angular2/core';
// set the selector for the element type to spy on.
@Directive({selector: 'select'})
export class DecoratorDirective {
constructor(el: ElementRef){
console.log(el)
}
}
@@ -0,0 +1,70 @@
import {Component, Input, Output, EventEmitter} from 'angular2/core';
import {Hero} from './hero';
let nextHeroDetailId = 1;
// #docregion input-output-2
@Component({
// #enddocregion input-output-2
selector: 'hero-detail',
// #docregion input-output-2
inputs: ['hero'],
outputs: ['deleted'],
// #enddocregion input-output-2
template: `
<div id="lh{{id}}">
{{hero?.fullName}}
<img src="{{heroImageUrl}}" style="height:24px">
<a href="#lh{{id}}" (click)="onDelete()">delete</a>
</div>`
// #docregion input-output-2
})
// #enddocregion input-output-2
export class HeroDetailComponent {
hero: Hero;
// #docregion deleted
deleted = new EventEmitter<Hero>();
onDelete() {
this.deleted.emit(this.hero);
}
// #enddocregion
// 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';
id = nextHeroDetailId++;
}
@Component({
selector: 'big-hero-detail',
/*
inputs: ['hero'],
outputs: ['deleted'],
*/
template: `
<div style="border: 1px solid black; padding:3px">
<img src="{{heroImageUrl}}" style="float:left; margin-right:8px;">
<div><b>{{hero?.fullName}}</b></div>
<div>First: {{hero?.firstName}}</div>
<div>Last: {{hero?.lastName}}</div>
<div>Birthdate: {{hero?.birthdate | date:'longDate'}}</div>
<div>Web: <a href="{{hero?.url}}" target="_blank">{{hero?.url}}</a></div>
<div>Rate/hr: {{hero?.rate | currency:'EUR'}}</div>
<br clear="all">
<button (click)="onDelete()">Delete</button>
</div>
`
})
export class BigHeroDetailComponent extends HeroDetailComponent {
// #docregion input-output-1
@Input() hero: Hero;
@Output() deleted = new EventEmitter<Hero>();
// #enddocregion input-output-1
onDelete() {
this.deleted.emit(this.hero);
}
}
@@ -0,0 +1,30 @@
export class Hero {
public id:number
constructor(
public firstName:string,
public lastName?:string,
public birthdate?:Date,
public url?:string,
public rate:number = 100) {
this.id = Hero.nextId++;
}
get fullName() {return `${this.firstName} ${this.lastName}`;}
static nextId = 1;
static MockHeroes = [
new Hero(
'Hercules',
'Son of Zeus',
new Date(1970, 1, 25),
'http://www.imdb.com/title/tt0065832/',
325),
new Hero('eenie', 'toe'),
new Hero('Meanie', 'Toe'),
new Hero('Miny', 'Toe'),
new Hero('Moe', 'Toe')
];
}
@@ -0,0 +1,32 @@
import {Directive, Output, ElementRef, EventEmitter} from 'angular2/core';
@Directive({selector:'[my-click]'})
export class MyClickDirective {
// #docregion my-click-output-1
@Output('myClick') clicks = new EventEmitter<string>();
// #enddocregion my-click-output-1
constructor(el: ElementRef){
el.nativeElement
.addEventListener('click', (event:Event) => {
this.clicks.emit('Click!');
});
}
}
// #docregion my-click-output-2
@Directive({
// #enddocregion my-click-output-2
selector:'[my-click2]',
// #docregion my-click-output-2
outputs:['clicks:myClick']
})
// #enddocregion my-click-output-2
export class MyClickDirective2 {
clicks = new EventEmitter<string>();
constructor(el: ElementRef){
el.nativeElement
.addEventListener('click', (event:Event) => {
this.clicks.emit('Click!');
});
}
}
@@ -2,21 +2,19 @@
<html>
<head>
<title>Template Syntax</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="styles.css">
<script src="../node_modules/systemjs/dist/system.src.js"></script>
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
<script>
System.config({
packages: {'app': {defaultExtension: 'js'}}
});
System.import('app/app');
System.import('app/boot');
</script>
</head>
<body>
<my-app>Loading...</my-app>
<hr>
<little-tour>Loading...</little-tour>
</body>
</html>
@@ -4,6 +4,8 @@ img {height: 100px;}
.child-div {margin-left: 1em; font-weight: normal}
.hidden {display: none}
.parent-div {margin-top: 1em; font-weight: bold}
.special {font-weight:bold;}
.special {font-weight:bold; font-size: x-large}
.bad {color: red;}
.curly {font-family: "Brush Script MT"}
.toe {margin-left: 1em; font-style: italic;}
little-hero {color:blue; font-size: smaller; background-color: Turquoise }
File diff suppressed because it is too large Load Diff
@@ -4,6 +4,8 @@ include ../../../../_includes/_util-fns
When the user clicks a link, pushes a button, or types on the keyboard
we want to know about it. These user actions all raise DOM events.
In this chapter we learn to bind to those events using the Angular Event Binding syntax.
[Live Example](/resources/live-examples/user-input/ts/src/plnkr.html).
:marked
## Binding to User Input Events
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB