docs(template-syntax): get closer to a Dart version of template-syntax
Add doc regions to the TS version. Update the Dart sample. Publish a hidden draft of the Dart version. Closes #758.
This commit is contained in:
parent
0f5ea46590
commit
3d87360432
|
@ -25,3 +25,5 @@ plnkr.html
|
|||
*plnkr.no-link.html
|
||||
public/docs/*/latest/guide/cheatsheet.json
|
||||
protractor-results.txt
|
||||
|
||||
public/docs/ts/latest/guide/_.*.jade
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
linter:
|
||||
rules:
|
||||
- always_declare_return_types
|
|
@ -1,15 +1,14 @@
|
|||
// #docregion
|
||||
library template_syntax.app_component;
|
||||
|
||||
import 'dart:html';
|
||||
import 'dart:convert';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:angular2/angular2.dart';
|
||||
import 'package:template_syntax/hero.dart';
|
||||
import 'package:template_syntax/hero_detail_component.dart';
|
||||
import 'package:template_syntax/my_click_directive.dart';
|
||||
|
||||
enum _Color { Red, Green, Blue }
|
||||
import 'hero.dart';
|
||||
import 'hero_detail_component.dart';
|
||||
import 'my_click_directive.dart';
|
||||
|
||||
enum Color { Red, Green, Blue }
|
||||
|
||||
@Component(
|
||||
selector: 'my-app',
|
||||
|
@ -24,37 +23,54 @@ class AppComponent {
|
|||
String heroName;
|
||||
String help;
|
||||
String actionName = 'Go for it';
|
||||
// String badCurly = 'special'; // XXX: This isn't working.
|
||||
// String badCurly = 'bad, curly'; // XXX: This isn't working.
|
||||
// String badCurly = 'bad curly'; // XXX: This isn't working.
|
||||
String badCurly = 'bad'; // XXX: This isn't working.
|
||||
// List<String> badCurly = ['bad', 'curly']; // XXX: This isn't working.
|
||||
String title = 'Template Syntax';
|
||||
String heroImageUrl = 'assets/images/hero.png';
|
||||
String villainImageUrl = 'assets/images/villain.png';
|
||||
String iconUrl = 'assets/images/ng-logo.png';
|
||||
String chosenToe;
|
||||
String toeChoice;
|
||||
int val = 2;
|
||||
bool canSave = true;
|
||||
bool isActive = false;
|
||||
bool isSpecial = true;
|
||||
bool isUnchanged = true;
|
||||
bool isSelected = false;
|
||||
_Color color = _Color.Red;
|
||||
Color color = Color.Red;
|
||||
List<Hero> heroes = Hero.MockHeroes;
|
||||
Hero selectedHero = Hero.MockHeroes[0];
|
||||
Hero currentHero = Hero.MockHeroes[0];
|
||||
Hero nullHero = null;
|
||||
final Hero nullHero = null;
|
||||
Map product = {'name': 'frimfram', 'price': 42};
|
||||
Event clickity;
|
||||
FormElement form;
|
||||
String clickity = '';
|
||||
String clickMessage = '';
|
||||
String clickMessage2 = '';
|
||||
final String iconUrl = 'assets/images/ng-logo.png';
|
||||
|
||||
// heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
|
||||
// Public Domain terms of use: http://www.wpclipart.com/terms.html
|
||||
final String heroImageUrl = 'assets/images/hero.png';
|
||||
|
||||
// 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
|
||||
final String villainImageUrl = 'assets/images/villain.png';
|
||||
|
||||
// #docregion setClasses
|
||||
Map classes = {
|
||||
'saveable': false, // true
|
||||
'modified': false, // false
|
||||
'special': false // true
|
||||
'saveable': false,
|
||||
'modified': false,
|
||||
'special': false
|
||||
};
|
||||
// #enddocregion setClasses
|
||||
|
||||
// #docregion setStyles
|
||||
Map styles = {
|
||||
'font-style': 'normal',
|
||||
'font-weight': 'normal',
|
||||
'font-size': 'smaller'
|
||||
};
|
||||
// #enddocregion setStyles
|
||||
|
||||
Map styles2 = {
|
||||
'fontStyle': 'normal',
|
||||
|
@ -66,31 +82,31 @@ class AppComponent {
|
|||
void callFax(String value) => alerter('Faxing $value ...');
|
||||
void callPhone(String value) => alerter('Calling $value ...');
|
||||
void colorToggle() {
|
||||
color = color == _Color.Red ? _Color.Blue : _Color.Red;
|
||||
color = (color == Color.Red) ? Color.Blue : Color.Red;
|
||||
}
|
||||
|
||||
int get getVal => val;
|
||||
int getVal() => val;
|
||||
|
||||
void onCancel(MouseEvent event) {
|
||||
DivElement el = event.target;
|
||||
var evtMsg = event != null ? 'Event target is ${el.innerHtml}' : '';
|
||||
var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : '';
|
||||
alerter('Canceled. $evtMsg');
|
||||
}
|
||||
|
||||
void onClickMe(MouseEvent event) {
|
||||
DivElement el = event.target;
|
||||
var evtMsg = event != null ? 'Event target class is ${el.className}' : '';
|
||||
var evtMsg = event != null ? 'Event target class is ${el.className}.' : '';
|
||||
alerter('Click me. $evtMsg');
|
||||
}
|
||||
|
||||
bool onSave([MouseEvent event = null]) {
|
||||
var evtMsg =
|
||||
event != null ? ' Event target is ${event.target.innerHtml}' : '';
|
||||
alerter('Saved.$evtMsg');
|
||||
event != null ? ' Event target is ${event.target.innerHtml}.' : '';
|
||||
alerter('Saved. $evtMsg');
|
||||
return false;
|
||||
}
|
||||
|
||||
void onHeroDeleted(Hero hero) => alerter('Deleted hero: ${hero.firstName}');
|
||||
void onHeroDeleted([Hero hero]) => alerter('Deleted hero: ${hero?.firstName}');
|
||||
|
||||
void onSubmit(NgForm form) {
|
||||
var evtMsg = form.valid
|
||||
|
@ -108,40 +124,32 @@ class AppComponent {
|
|||
return JSON.encode(showStyles);
|
||||
}
|
||||
|
||||
// #docregion setStyles
|
||||
Map setStyles() {
|
||||
styles['font-style'] = canSave ? 'italic' : 'normal';
|
||||
styles['font-weight'] = !isUnchanged ? 'bold' : 'normal';
|
||||
styles['font-size'] = isSpecial ? 'x-large' : 'smaller';
|
||||
return styles;
|
||||
}
|
||||
// #enddocregion setStyles
|
||||
|
||||
// #docregion setStyles2
|
||||
Map setStyles2() {
|
||||
// camelCase style properties work too [PENDING: no, they don't]
|
||||
styles2['fontStyle'] = canSave ? 'italic' : 'normal';
|
||||
styles2['fontWeight'] = !isUnchanged ? 'bold' : 'normal';
|
||||
styles2['fontSize'] = isSpecial ? 'x-large' : 'smaller';
|
||||
return styles2;
|
||||
}
|
||||
// #enddocregion setStyles2
|
||||
|
||||
// #docregion setClasses
|
||||
Map setClasses() {
|
||||
classes['saveable'] = canSave;
|
||||
classes['modified'] = !isUnchanged;
|
||||
classes['special'] = isSpecial;
|
||||
classes['saveable'] = canSave; // true
|
||||
classes['modified'] = !isUnchanged; // false
|
||||
classes['special'] = isSpecial; // true
|
||||
|
||||
return classes;
|
||||
}
|
||||
// #enddocregion setClasses
|
||||
|
||||
// #docregion setStyles
|
||||
Map setStyles() {
|
||||
styles['font-style'] = canSave ? 'italic' : 'normal'; // italic
|
||||
styles['font-weight'] = !isUnchanged ? 'bold' : 'normal'; // normal
|
||||
styles['font-size'] = isSpecial ? '24px' : '8px'; // 24px
|
||||
return styles;
|
||||
}
|
||||
// #enddocregion setStyles
|
||||
|
||||
String toeChooser(Element picker) {
|
||||
List<Element> choices = picker.children;
|
||||
for (var i = 0; i < choices.length; i++) {
|
||||
var choice = choices[i];
|
||||
if (choice.checked) {
|
||||
chosenToe = choice.value;
|
||||
return chosenToe;
|
||||
toeChoice = choice.value;
|
||||
return toeChoice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<!-- #docregion sum-2 -->
|
||||
<!-- "The sum of 1 + 1 is not 4" -->
|
||||
<p>The sum of 1 + 1 is not {{1 + 1 + getVal}}</p>
|
||||
<p>The sum of 1 + 1 is not {{1 + 1 + getVal()}}</p>
|
||||
<!-- #enddocregion sum-2 -->
|
||||
|
||||
|
||||
|
@ -69,9 +69,9 @@
|
|||
<!-- #docregion event-binding-syntax-1 -->
|
||||
<button (click) = "onSave()">Save</button>
|
||||
<hero-detail (deleted)="onHeroDeleted()"></hero-detail>
|
||||
<div myClick (myClick)="clicked=$event">click me</div>
|
||||
<div myClick (myClick)="clickity=$event">click me</div>
|
||||
<!-- #enddocregion event-binding-syntax-1 -->
|
||||
<!-- {{clicked}} --> <!-- causes exception in Dart version -->
|
||||
{{clickity}}
|
||||
<br><br>
|
||||
|
||||
<div>
|
||||
|
@ -146,15 +146,17 @@ button</button>
|
|||
|
||||
<!-- #docregion property-binding-6 -->
|
||||
<!-- Doesn't work! HeroDetailComponent expects a Hero, not a string -->
|
||||
<!--<hero-detail hero="…what do we do here??? …"></hero-detail>--> <!--THROWS ERROR IN DART-->
|
||||
<!-- <hero-detail hero="…what do we do here??? …"></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-vs-interpolation -->
|
||||
<img src="{{heroImageUrl}}">
|
||||
<img [src]="'' + heroImageUrl">
|
||||
<img [src]="heroImageUrl">
|
||||
|
||||
<div>The title is {{title}}</div>
|
||||
<div [textContent]="'The title is '+title"></div>
|
||||
<div [textContent]="'The title is ' + title"></div>
|
||||
<!-- #enddocregion property-binding-vs-interpolation -->
|
||||
|
||||
<!-- attribute binding -->
|
||||
|
@ -208,9 +210,10 @@ button</button>
|
|||
<!-- #enddocregion class-binding-1 -->
|
||||
|
||||
<!-- #docregion class-binding-2 -->
|
||||
<!-- reset all class names with a string binding -->
|
||||
<!-- reset/override all class names with a binding -->
|
||||
<div class="bad curly special"
|
||||
[class]="'bad curly'">Bad curly</div>
|
||||
[class]="badCurly">Bad curly</div> <!-- Doesn't work, due to
|
||||
github.com/angular/angular/issues/6901 -->
|
||||
<!-- #enddocregion class-binding-2 -->
|
||||
|
||||
<!-- #docregion class-binding-3 -->
|
||||
|
@ -257,10 +260,10 @@ button</button>
|
|||
<!-- `myClick` is an event on the custom `MyClickDirective` -->
|
||||
|
||||
<!-- #docregion my-click -->
|
||||
<div myClick (myClick)="clickity=$event">click with myClick</div>
|
||||
<div myClick (myClick)="clickMessage=$event">click with myClick</div>
|
||||
<!-- #enddocregion my-click -->
|
||||
<!-- #enddocregion event-binding-3 -->
|
||||
{{clickity}}
|
||||
{{clickMessage}}
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -362,32 +365,22 @@ bindon-ngModel
|
|||
|
||||
<!-- #docregion NgStyle-1 -->
|
||||
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
|
||||
This div is x-large
|
||||
This div is x-large.
|
||||
</div>
|
||||
<!-- #enddocregion NgStyle-1 -->
|
||||
|
||||
<h3>Use setStyles() - CSS property names</h3>
|
||||
<p>setStyles returns {{setStyles() | json}}</p>
|
||||
<p>setStyles returns {{setStyles()}}.</p>
|
||||
<!-- #docregion NgStyle-2 -->
|
||||
<div [ngStyle]="setStyles()">
|
||||
This div is italic, normal weight, and x-large
|
||||
This div is italic, normal weight, and extra large (24px).
|
||||
</div>
|
||||
<!-- #enddocregion NgStyle-2 -->
|
||||
<div [ngStyle]="setStyles()" #styleDiv>
|
||||
After setStyles(), the styles are "{{getStyles(styleDiv)}}"
|
||||
</div>
|
||||
|
||||
|
||||
<h3>Use setStyles2() - camelCase style property names</h3>
|
||||
<p>setStyles2 returns {{setStyles2() | json}}</p>
|
||||
<!-- #docregion NgStyle-3 -->
|
||||
<div [ngStyle]="setStyles2()">
|
||||
This div is italic, normal weight, and x-large
|
||||
</div>
|
||||
<!-- #enddocregion NgStyle-3 -->
|
||||
<div [ngStyle]="setStyles2()" #styleDiv2>
|
||||
After setStyles2(), the styles are "{{getStyles(styleDiv2)}}"
|
||||
</div>
|
||||
<p>After setStyles(), the DOM confirms that the styles are
|
||||
<span [ngStyle]="setStyles()" #styleDiv>
|
||||
{{getStyles(styleDiv)}}
|
||||
</span>.
|
||||
</p>
|
||||
|
||||
<!-- not used in chapter -->
|
||||
|
||||
|
@ -401,7 +394,7 @@ bindon-ngModel
|
|||
<!-- #enddocregion NgIf-1 -->
|
||||
|
||||
<!-- #docregion NgIf-2 -->
|
||||
<!-- not displayed because nullHero is falsey.
|
||||
<!-- not displayed because nullHero is false.
|
||||
`nullHero.firstName` never has a chance to fail -->
|
||||
<div *ngIf="nullHero != null">Hello, {{nullHero.firstName}}</div>
|
||||
|
||||
|
@ -446,17 +439,17 @@ bindon-ngModel
|
|||
</fieldset>
|
||||
|
||||
<div class="toe">
|
||||
<div *ngIf="chosenToe == null">Pick a toe</div>
|
||||
<div *ngIf="chosenToe != null">You picked
|
||||
<!-- #docregion NgSwitch -->
|
||||
<span [ngSwitch]="chosenToe">
|
||||
<template [ngSwitchWhen]="'Eenie'">Eenie</template>
|
||||
<template [ngSwitchWhen]="'Meanie'">Meanie</template>
|
||||
<template [ngSwitchWhen]="'Miney'">Miney</template>
|
||||
<template [ngSwitchWhen]="'Moe'">Moe</template>
|
||||
<template ngSwitchDefault>Other</template>
|
||||
</span>
|
||||
<!-- #enddocregion NgSwitch -->
|
||||
<div *ngIf="toeChoice == null">Pick a toe</div>
|
||||
<div *ngIf="toeChoice != null">You picked
|
||||
<!-- #docregion NgSwitch -->
|
||||
<span [ngSwitch]="toeChoice">
|
||||
<template [ngSwitchWhen]="'Eenie'">Eenie</template>
|
||||
<template [ngSwitchWhen]="'Meanie'">Meanie</template>
|
||||
<template [ngSwitchWhen]="'Miney'">Miney</template>
|
||||
<template [ngSwitchWhen]="'Moe'">Moe</template>
|
||||
<template ngSwitchDefault>Other</template>
|
||||
</span>
|
||||
<!-- #enddocregion NgSwitch -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -480,8 +473,8 @@ bindon-ngModel
|
|||
<br>
|
||||
|
||||
<div class="box">
|
||||
<!-- #docregion NgFor-3 -->
|
||||
<!-- Ex: 1 - Hercules Son of Zeus -->
|
||||
<!-- #docregion NgFor-3 -->
|
||||
<div *ngFor="#hero of heroes, #i=index">{{i + 1}} - {{hero.fullName}}</div>
|
||||
<!-- #enddocregion NgFor-3 -->
|
||||
</div>
|
||||
|
@ -567,10 +560,8 @@ bindon-ngModel
|
|||
</hero-detail>
|
||||
<!-- #enddocregion io-2 -->
|
||||
|
||||
<!-- <div myClick2 (myClick)="clicked2=$event">myClick2</div>
|
||||
{{clicked2}}
|
||||
PENDING: I don't see clicked2 defined anywhere in the TS example
|
||||
-->
|
||||
<div myClick2 (myClick)="clickMessage2=$event">myClick2</div>
|
||||
{{clickMessage2}}
|
||||
|
||||
<!-- Pipes -->
|
||||
<hr><h2>Pipes</h2>
|
||||
|
@ -591,14 +582,10 @@ PENDING: I don't see clicked2 defined anywhere in the TS example
|
|||
<!-- #enddocregion pipes-3 -->
|
||||
|
||||
<!-- #docregion pipes-json -->
|
||||
<!--<div>{{currentHero | json}}</div>--> <!-- PENDING: uncomment? -->
|
||||
<!-- 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>-->
|
||||
|
||||
<!-- Output:
|
||||
{ "firstName": "Hercules", "lastName": "Son of Zeus",
|
||||
"birthdate": "1970-02-25T08:00:00.000Z",
|
||||
"url": "http://www.imdb.com/title/tt0065832/",
|
||||
"rate": 325, "id": 1 }
|
||||
-->
|
||||
<!-- #enddocregion pipes-json -->
|
||||
|
||||
|
||||
|
@ -606,7 +593,7 @@ PENDING: I don't see clicked2 defined anywhere in the TS example
|
|||
|
||||
<div>
|
||||
<!-- pipe price to USD and display the $ symbol -->
|
||||
<!--<label>Price: </label>{{product.price | currency:'USD':true}}--> <!-- PENDING: uncomment? -->
|
||||
<label>Price: </label>{{product['price'] | currency:'$'}}
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -632,11 +619,12 @@ PENDING: I don't see clicked2 defined anywhere in the TS example
|
|||
</div>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
The null hero's name is {{nullHero.firstName}}
|
||||
|
||||
See console log
|
||||
TypeError: Cannot read property 'firstName' of null in [null]
|
||||
See console log:
|
||||
EXCEPTION: The null object does not have a getter 'firstName'.
|
||||
-->
|
||||
|
||||
<!-- #docregion elvis-4 -->
|
||||
|
@ -644,11 +632,7 @@ See console log
|
|||
<div *ngIf="nullHero != null">The null hero's name is {{nullHero.firstName}}</div>
|
||||
<!-- #enddocregion elvis-4 -->
|
||||
|
||||
<div>
|
||||
<!-- #docregion elvis-5 -->
|
||||
The null hero's name is {{nullHero != null && nullHero.firstName != null}} <!-- PENDING: ??? -->
|
||||
<!-- #enddocregion elvis-5 -->
|
||||
</div>
|
||||
<!-- skip docregion elvis-5 -->
|
||||
|
||||
<div>
|
||||
<!-- #docregion elvis-6 -->
|
||||
|
@ -660,8 +644,9 @@ See console log
|
|||
|
||||
<!-- Todo: discuss this in the Style binding section -->
|
||||
<!-- enums in bindings -->
|
||||
<!--
|
||||
<hr><h2>Enums in binding</h2>
|
||||
|
||||
<p>The name of the Color.Red enum is {{color}}</p> <!-- PENDING: Color[Color.Red]?? -->
|
||||
<p>The current color number is {{color}}</p>
|
||||
<p><button [style.color]="color" (click)="colorToggle()">Enum Toggle</button> <!-- PENDING: color -> Color[color]? -->
|
||||
<p><button [style.color]="color.toString()" (click)="colorToggle()">Enum Toggle</button>
|
||||
-->
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// #docregion
|
||||
library template_syntax.hero;
|
||||
|
||||
class Hero {
|
||||
static int _nextId = 1;
|
||||
|
||||
|
@ -18,7 +16,7 @@ class Hero {
|
|||
static List<Hero> MockHeroes = [
|
||||
new Hero('Hercules',
|
||||
lastName: 'Son of Zeus',
|
||||
birthdate: new DateTime(1970, 1, 25),
|
||||
birthdate: new DateTime(1970, 2, 25),
|
||||
url: 'http://www.imdb.com/title/tt0065832/',
|
||||
rate: 325),
|
||||
new Hero('eenie', lastName: 'toe'),
|
||||
|
@ -27,5 +25,10 @@ class Hero {
|
|||
new Hero('Moe', lastName: 'Toe')
|
||||
];
|
||||
|
||||
String get fullName => '$firstName $lastName';
|
||||
String get fullName {
|
||||
if (lastName == null) return firstName;
|
||||
return '$firstName $lastName';
|
||||
}
|
||||
|
||||
String toString() => '$fullName (rate: $rate)';
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
library template_syntax.hero_detail_component;
|
||||
|
||||
import 'package:angular2/angular2.dart';
|
||||
import 'package:template_syntax/hero.dart';
|
||||
|
||||
import 'hero.dart';
|
||||
|
||||
var nextHeroDetailId = 1;
|
||||
|
||||
|
@ -11,28 +11,40 @@ var nextHeroDetailId = 1;
|
|||
// #enddocregion input-output-2
|
||||
selector: 'hero-detail',
|
||||
// #docregion input-output-2
|
||||
// ...
|
||||
inputs: const ['hero'],
|
||||
outputs: const ['deleted'],
|
||||
// #enddocregion input-output-2
|
||||
template: '''<div id="lh{{hero?.id}}">
|
||||
{{hero?.fullName}}
|
||||
template: '''
|
||||
<div>
|
||||
<span [style.text-decoration]="lineThrough" >{{hero?.fullName}}</span>
|
||||
<img src="{{heroImageUrl}}" style="height:24px">
|
||||
<a href="#lh{{hero?.id}}" (click)="onDelete()">delete</a>
|
||||
</div>'''
|
||||
<a (click)="onDelete()">delete</a>
|
||||
</div>
|
||||
'''
|
||||
// #docregion input-output-2
|
||||
)
|
||||
// #enddocregion input-output-2
|
||||
class HeroDetailComponent {
|
||||
Hero hero;
|
||||
// #docregion deleted
|
||||
|
||||
Hero hero = new Hero('Zzzzzzzz'); // default sleeping hero
|
||||
String heroImageUrl = 'assets/images/hero.png';
|
||||
final EventEmitter deleted = new EventEmitter<Hero>();
|
||||
String lineThrough = ''; // PENDING: use null instead?
|
||||
|
||||
onDelete() {
|
||||
deleted.add(hero);
|
||||
// #docregion deleted
|
||||
final EventEmitter deleted = new EventEmitter<Hero>();
|
||||
// #enddocregion deleted
|
||||
|
||||
HeroDetailComponent() {
|
||||
deleted.listen((Hero _) {
|
||||
lineThrough = (lineThrough == '') ? 'line-through' : '';
|
||||
});
|
||||
}
|
||||
// #enddocregion deleted
|
||||
|
||||
// #docregion deleted
|
||||
onDelete() {
|
||||
deleted.emit(hero);
|
||||
}
|
||||
// #enddocregion deleted
|
||||
}
|
||||
|
||||
@Component(
|
||||
|
@ -41,7 +53,8 @@ class HeroDetailComponent {
|
|||
inputs: ['hero'],
|
||||
outputs: ['deleted'],
|
||||
*/
|
||||
template: '''<div style="border: 1px solid black; padding:3px">
|
||||
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>
|
||||
|
@ -51,17 +64,17 @@ class HeroDetailComponent {
|
|||
<div>Rate/hr: {{hero?.rate | currency:'EUR'}}</div>
|
||||
<br clear="all">
|
||||
<button (click)="onDelete()">Delete</button>
|
||||
</div>''')
|
||||
</div>
|
||||
''')
|
||||
class BigHeroDetailComponent extends HeroDetailComponent {
|
||||
// #docregion input-output-1
|
||||
@Input() Hero hero;
|
||||
@Output()
|
||||
final EventEmitter deleted = new EventEmitter<Hero>();
|
||||
@Output() final EventEmitter deleted = new EventEmitter<Hero>();
|
||||
// #enddocregion input-output-1
|
||||
|
||||
String heroImageUrl = 'assets/images/hero.png';
|
||||
|
||||
onDelete() {
|
||||
deleted.add(hero);
|
||||
deleted.emit(hero);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// #docregion
|
||||
library template_syntax.my_click_directive;
|
||||
|
||||
// #docplaster
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:angular2/angular2.dart';
|
||||
|
@ -8,12 +6,18 @@ import 'package:angular2/angular2.dart';
|
|||
@Directive(selector: '[myClick]')
|
||||
class MyClickDirective {
|
||||
// #docregion my-click-output-1
|
||||
@Output()
|
||||
final EventEmitter clicks = new EventEmitter<String>();
|
||||
// @Output(alias) [type info] propertyName = ...
|
||||
@Output('myClick') final EventEmitter clicks = new EventEmitter<String>();
|
||||
|
||||
// #enddocregion my-click-output-1
|
||||
bool _toggle = false;
|
||||
|
||||
MyClickDirective(ElementRef el) {
|
||||
el.nativeElement.onClick.listen(this.clicks.add('Click!'));
|
||||
Element nativeEl = el.nativeElement;
|
||||
nativeEl.onClick.listen((Event e) {
|
||||
_toggle = !_toggle;
|
||||
clicks.emit(_toggle ? 'Click!' : '');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,12 +26,17 @@ class MyClickDirective {
|
|||
// #enddocregion my-click-output-2
|
||||
selector: '[myClick2]',
|
||||
// #docregion my-click-output-2
|
||||
outputs: const ['clicks:myClick'])
|
||||
// ...
|
||||
outputs: const ['clicks:myClick']) // propertyName:alias
|
||||
// #enddocregion my-click-output-2
|
||||
class MyClickDirective2 {
|
||||
final EventEmitter clicks = new EventEmitter<String>();
|
||||
bool _toggle = false;
|
||||
|
||||
MyClickDirective(ElementRef el) {
|
||||
el.nativeElement.onClick.listen(this.clicks.add('Click!'));
|
||||
MyClickDirective2(ElementRef el) {
|
||||
el.nativeElement.onClick.listen((Event e) {
|
||||
_toggle = !_toggle;
|
||||
clicks.emit(_toggle ? 'Click2!' : '');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
# #docregion
|
||||
name: template_syntax
|
||||
description: Template Syntax
|
||||
version: 0.0.1
|
||||
environment:
|
||||
sdk: '>=1.13.0 <2.0.0'
|
||||
dependencies:
|
||||
angular2: 2.0.0-beta.0
|
||||
angular2: 2.0.0-beta.3
|
||||
browser: ^0.10.0
|
||||
dart_to_js_script_rewriter: ^0.1.0
|
||||
transformers:
|
||||
- angular2:
|
||||
platform_pipes: 'package:angular2/common.dart#COMMON_PIPES'
|
||||
platform_directives:
|
||||
- 'package:angular2/common.dart#COMMON_DIRECTIVES'
|
||||
- 'package:angular2/common.dart#FORM_DIRECTIVES'
|
||||
entry_points: web/main.dart
|
||||
- dart_to_js_script_rewriter
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Template Syntax</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<script defer src="main.dart" type="application/dart"></script>
|
||||
<script defer src="packages/browser/dart.js"></script>
|
||||
</head>
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
include ../../../../_includes/_util-fns
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'intro')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'html-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'my-first-app')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'html-2')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'first-interpolation')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'title+image')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'sum-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-4')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'sum-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-5')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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: **[QUESTION: is this list correct? I removed mentions of chaining with , and ;.]**
|
||||
|
||||
* assignments (`=`, `+=`, `-=`, ...)
|
||||
* creating instances using `new` or `const`
|
||||
* increment and decrement (`++` and `--`)
|
||||
|
||||
Other notable differences from Dart syntax include:
|
||||
**[QUESTION: I wasn't able to use Dart interpolation inside a String,
|
||||
which I had just assumed would work. How should we talk about that?
|
||||
What else isn't allowed?]**
|
||||
|
||||
* no support for the bitwise operators `|` and `&`
|
||||
* new [template expression operators](#expression-operators), such as `|`
|
||||
.callout.is-helpful
|
||||
header Dart difference: Template expression operators
|
||||
:marked
|
||||
[PENDING: say something about stuff you might find in a24ts template expressions
|
||||
but not in dart template expressions, and vice versa.]
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-expressions-context')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-expressions-guidelines')
|
||||
:marked
|
||||
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/latest/guide/template-syntax.jade', '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 (`;`) and commas (`,`).
|
||||
**[QUESTION: is that true — would `,` really work? is "chaining" really the word we want to use?]**
|
||||
|
||||
However, certain Dart syntax is not allowed:
|
||||
* the `new` and `const` keywords **[QUESTION: I guessed about `const`. Is it true?]**
|
||||
* increment and decrement operators, `++` and `--`
|
||||
* operator assignment, such as `+=` and `-=`
|
||||
* the bitwise operators `|` and `&`
|
||||
* the [template expression operators](#expression-operators)
|
||||
**[QUESTION: can you really not use `?.`?]**
|
||||
|
||||
.callout.is-helpful
|
||||
header Dart difference: Template statement operators
|
||||
:marked
|
||||
[PENDING: say something about stuff you might find in a24ts statements
|
||||
but not in dart statements, and vice versa.]
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-statements-3')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'img+button')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'hero-detail-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'disabled-button-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-4')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-attribute-vs-property')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-5')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-world-without-attributes')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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/latest/guide/template-syntax.jade', 'binding-syntax-end')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-4')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-5')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-6')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-7')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-8')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-5')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-9')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-10')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-11')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-6')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-12')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-vs-interpolation')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-13')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-1')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-colspan')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-aria')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-class-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-class-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-2')(format=".")
|
||||
//
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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/latest/guide/template-syntax.jade', 'other-bindings-class-4')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-style-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-style-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-style-3')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-4')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-5')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-6')
|
||||
+makeExample('template-syntax/dart/lib/hero_detail_component.dart', 'deleted', 'lib/hero_detail_component.dart (excerpt)')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-7')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-to-component')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-8')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-4')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-5')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-6')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-4')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-7')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-2')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngClass-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-3a')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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/latest/guide/template-syntax.jade', 'directives-ngClass-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgClass-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngStyle-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngStyle-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.dart', 'setStyles')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngStyle-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-2')(format=".")
|
||||
//
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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/latest/guide/template-syntax.jade', 'directives-ngIf-2')
|
||||
//
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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 error messages such as
|
||||
"[TODO: Put error message here]".
|
||||
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/latest/guide/template-syntax.jade', 'directives-ngIf-4')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngIf-5')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngSwitch-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgSwitch')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngSwitch-2')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-3')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-4')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-5')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-6')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-7')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngIf-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngIf-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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. **[QUESTION: Did I get that right?]**
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-3')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-3')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-4')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-4')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-4')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-2')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-refs')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'var-phone')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-value')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-form-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'var-form')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-form-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'var-form-a')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-form-3')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'io-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'io-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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/latest/guide/template-syntax.jade', 'inputs-outputs-4')
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-5')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'my-click')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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
|
||||
for specific scenarios. We'll cover two of these operators: _pipe_ and _Elvis_.
|
||||
.callout.is-helpful
|
||||
header Dart difference: ?. is a Dart operator
|
||||
:marked
|
||||
The Elvis operator (`?.`) is part of the Dart language.
|
||||
It's considered a template expression operator because
|
||||
Angular 2 supports `?.` even in TypeScript and JavaScript apps.
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-pipe-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'pipes-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-pipe-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'pipes-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', '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/latest/guide/template-syntax.jade', 'expression-operators-pipe-4')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'pipes-json')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-1')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-2')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-2')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-1')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-3')
|
||||
// +includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-4')
|
||||
:marked
|
||||
Dart throws an exception, and so does Angular:
|
||||
code-example(format="" language="html").
|
||||
EXCEPTION: The null object does not have a getter 'firstName'.
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-5')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-4')(format=".")
|
||||
|
||||
//
|
||||
NOTE: Intentionally skip ugly null checking you wouldn't do in Dart.
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-6')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-5')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-7')
|
||||
: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`.
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-8')
|
||||
+makeExample('template-syntax/dart/lib/app_component.html', 'elvis-6')(format=".")
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-9')
|
||||
|
||||
+includeShared('../../../ts/latest/guide/template-syntax.jade', 'summary')
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue