docs(template-syntax): review and update Dart to new doc design (#1465)
* ts template-syntax.jade without docregion tags * update guide/template-syntax for dart and ts * clarify style property naming in Dart
This commit is contained in:
parent
e8f84cfc04
commit
a664f46231
public
_includes
docs
_examples/template-syntax
dart
ts/app
dart/latest
ts/latest/guide
@ -21,6 +21,7 @@
|
|||||||
- var _an = 'an';
|
- var _an = 'an';
|
||||||
|
|
||||||
//- TS arrays vs. Dart lists
|
//- TS arrays vs. Dart lists
|
||||||
|
- var _Array = 'Array';
|
||||||
- var _array = 'array';
|
- var _array = 'array';
|
||||||
//- Deprecate now that we have the articles _a and _an
|
//- Deprecate now that we have the articles _a and _an
|
||||||
- var _an_array = 'an array';
|
- var _an_array = 'an array';
|
||||||
@ -32,6 +33,9 @@
|
|||||||
//- Location of sample code
|
//- Location of sample code
|
||||||
- var _liveLink = 'live link';
|
- var _liveLink = 'live link';
|
||||||
|
|
||||||
|
//- Other
|
||||||
|
- var _truthy = 'truthy';
|
||||||
|
- var _falsey = 'falsey';
|
||||||
|
|
||||||
//- Used to prefix identifiers that are private. In Dart this will be '_'.
|
//- Used to prefix identifiers that are private. In Dart this will be '_'.
|
||||||
- var _priv = '';
|
- var _priv = '';
|
||||||
@ -39,8 +43,8 @@
|
|||||||
//- Use to conditionally include the block that follows +ifDocsFor(...).
|
//- Use to conditionally include the block that follows +ifDocsFor(...).
|
||||||
//- Generally favor use of Jade named blocks instead. ifDocsFor is convenient
|
//- Generally favor use of Jade named blocks instead. ifDocsFor is convenient
|
||||||
//- for prose that should appear only in one language version.
|
//- for prose that should appear only in one language version.
|
||||||
mixin ifDocsFor(lang)
|
mixin ifDocsFor(langPattern)
|
||||||
if _docsFor.toLowerCase() === lang.toLowerCase()
|
if _docsFor.toLowerCase().match(langPattern.toLowerCase())
|
||||||
block
|
block
|
||||||
|
|
||||||
//- Use to map inlined (prose) TS paths into, say, Dart paths via the
|
//- Use to map inlined (prose) TS paths into, say, Dart paths via the
|
||||||
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
|
|
||||||
import 'package:angular2/core.dart';
|
import 'package:angular2/core.dart';
|
||||||
|
import 'package:angular2/common.dart';
|
||||||
|
|
||||||
import 'hero.dart';
|
import 'hero.dart';
|
||||||
import 'hero_detail_component.dart';
|
import 'hero_detail_component.dart';
|
||||||
@ -40,7 +41,9 @@ class AppComponent implements OnInit, AfterViewInit {
|
|||||||
bool isSpecial = true;
|
bool isSpecial = true;
|
||||||
bool isUnchanged = true;
|
bool isUnchanged = true;
|
||||||
bool isSelected = false;
|
bool isSelected = false;
|
||||||
|
final Color colorRed = Color.red;
|
||||||
Color color = Color.red;
|
Color color = Color.red;
|
||||||
|
var colorEnum = Color;
|
||||||
|
|
||||||
List<Hero> heroes;
|
List<Hero> heroes;
|
||||||
Hero currentHero;
|
Hero currentHero;
|
||||||
@ -56,7 +59,7 @@ class AppComponent implements OnInit, AfterViewInit {
|
|||||||
final Hero nullHero = null;
|
final Hero nullHero = null;
|
||||||
Map product = {'name': 'frimfram', 'price': 42};
|
Map product = {'name': 'frimfram', 'price': 42};
|
||||||
FormElement form;
|
FormElement form;
|
||||||
String clickity = '';
|
String clicked = '';
|
||||||
String clickMessage = '';
|
String clickMessage = '';
|
||||||
String clickMessage2 = '';
|
String clickMessage2 = '';
|
||||||
final String iconUrl = 'assets/images/ng-logo.png';
|
final String iconUrl = 'assets/images/ng-logo.png';
|
||||||
@ -87,14 +90,14 @@ class AppComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
int getVal() => val;
|
int getVal() => val;
|
||||||
|
|
||||||
void onCancel(MouseEvent event) {
|
void onCancel(UIEvent event) {
|
||||||
DivElement el = event.target;
|
HtmlElement el = event?.target;
|
||||||
var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : '';
|
var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : '';
|
||||||
alerter('Canceled. $evtMsg');
|
alerter('Canceled. $evtMsg');
|
||||||
}
|
}
|
||||||
|
|
||||||
void onClickMe(MouseEvent event) {
|
void onClickMe(UIEvent event) {
|
||||||
DivElement el = event.target;
|
HtmlElement 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');
|
alerter('Click me. $evtMsg');
|
||||||
}
|
}
|
||||||
@ -103,9 +106,10 @@ class AppComponent implements OnInit, AfterViewInit {
|
|||||||
alerter('Deleted hero: ${hero?.firstName}');
|
alerter('Deleted hero: ${hero?.firstName}');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool onSave([MouseEvent event = null]) {
|
bool onSave([UIEvent event = null]) {
|
||||||
|
HtmlElement el = event?.target;
|
||||||
var evtMsg =
|
var evtMsg =
|
||||||
event != null ? ' Event target is ${event.target.innerHtml}.' : '';
|
event != null ? ' Event target is ${el.innerHtml}.' : '';
|
||||||
alerter('Saved. $evtMsg');
|
alerter('Saved. $evtMsg');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<a href="#star-prefix">* prefix and <template></a><br>
|
<a href="#star-prefix">* prefix and <template></a><br>
|
||||||
<a href="#local-vars">Template local variables</a><br>
|
<a href="#ref-vars">Template reference variables</a><br>
|
||||||
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
|
<a href="#inputs-and-outputs">Inputs and outputs</a><br>
|
||||||
<a href="#pipes">Pipes</a><br>
|
<a href="#pipes">Pipes</a><br>
|
||||||
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
|
<a href="#safe-navigation-operator">Safe navigation operator <i>?.</i></a><br>
|
||||||
<!--<a href="#enums">Enums</a><br>-->
|
<a href="#enums">Enums</a><br>
|
||||||
|
|
||||||
<!-- Interpolation and expressions -->
|
<!-- Interpolation and expressions -->
|
||||||
<hr><h2 id="interpolation">Interpolation</h2>
|
<hr><h2 id="interpolation">Interpolation</h2>
|
||||||
@ -105,9 +105,9 @@
|
|||||||
<!-- #docregion event-binding-syntax-1 -->
|
<!-- #docregion event-binding-syntax-1 -->
|
||||||
<button (click) = "onSave()">Save</button>
|
<button (click) = "onSave()">Save</button>
|
||||||
<hero-detail (deleteRequest)="deleteHero()"></hero-detail>
|
<hero-detail (deleteRequest)="deleteHero()"></hero-detail>
|
||||||
<div (myClick)="clickity=$event">click me</div>
|
<div (myClick)="clicked=$event">click me</div>
|
||||||
<!-- #enddocregion event-binding-syntax-1 -->
|
<!-- #enddocregion event-binding-syntax-1 -->
|
||||||
{{clickity}}
|
{{clicked}}
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -184,15 +184,14 @@ button</button>
|
|||||||
<!-- #enddocregion property-binding-5 -->
|
<!-- #enddocregion property-binding-5 -->
|
||||||
|
|
||||||
<!-- #docregion property-binding-6 -->
|
<!-- #docregion property-binding-6 -->
|
||||||
<!-- BAD! HeroDetailComponent.hero expects a Hero object,
|
<!-- ERROR: HeroDetailComponent.hero expects a
|
||||||
not the string "currentHero".
|
Hero object, not the string "currentHero" -->
|
||||||
|
|
||||||
<hero-detail hero="currentHero"></hero-detail> -->
|
|
||||||
<!-- #enddocregion property-binding-6 -->
|
<!-- #enddocregion property-binding-6 -->
|
||||||
|
<div *ngIf="false">
|
||||||
<!-- In checked mode, uncommenting the hero-detail above causes this:
|
<!-- #docregion property-binding-6 -->
|
||||||
EXCEPTION: type 'String' is not a subtype of type 'Hero' of 'value'. -->
|
<hero-detail hero="currentHero"></hero-detail>
|
||||||
|
<!-- #enddocregion property-binding-6 -->
|
||||||
|
</div>
|
||||||
<!-- #docregion property-binding-7 -->
|
<!-- #docregion property-binding-7 -->
|
||||||
<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>
|
<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>
|
||||||
<!-- #enddocregion property-binding-7 -->
|
<!-- #enddocregion property-binding-7 -->
|
||||||
@ -202,7 +201,7 @@ Interpolated: <img src="{{heroImageUrl}}"><br>
|
|||||||
Property bound: <img [src]="heroImageUrl">
|
Property bound: <img [src]="heroImageUrl">
|
||||||
|
|
||||||
<div>The interpolated title is {{title}}</div>
|
<div>The interpolated title is {{title}}</div>
|
||||||
<div [textContent]="'The [textContent] title is '+title"></div>
|
<div [innerHTML]="'The [innerHTML] title is '+title"></div>
|
||||||
<!-- #enddocregion property-binding-vs-interpolation -->
|
<!-- #enddocregion property-binding-vs-interpolation -->
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
@ -258,9 +257,7 @@ Property bound: <img [src]="heroImageUrl">
|
|||||||
<!-- #docregion class-binding-2 -->
|
<!-- #docregion class-binding-2 -->
|
||||||
<!-- reset/override all class names with a binding -->
|
<!-- reset/override all class names with a binding -->
|
||||||
<div class="bad curly special"
|
<div class="bad curly special"
|
||||||
[class]="badCurly">Bad curly</div>
|
[className]="badCurly">Bad curly</div>
|
||||||
<p><b>Note:</b> "Bad curly" should be smaller but isn't, due to
|
|
||||||
<a href="http://github.com/angular/angular/issues/6901">issue #6901</a>.</p>
|
|
||||||
<!-- #enddocregion class-binding-2 -->
|
<!-- #enddocregion class-binding-2 -->
|
||||||
|
|
||||||
<!-- #docregion class-binding-3 -->
|
<!-- #docregion class-binding-3 -->
|
||||||
@ -374,15 +371,15 @@ bindon-ngModel
|
|||||||
<br>
|
<br>
|
||||||
<!-- #docregion NgModel-3 -->
|
<!-- #docregion NgModel-3 -->
|
||||||
<input
|
<input
|
||||||
[ngModel]="currentHero.firstName"
|
[ngModel]="currentHero.firstName"
|
||||||
(ngModelChange)="currentHero.firstName=$event">
|
(ngModelChange)="currentHero.firstName=$event">
|
||||||
<!-- #enddocregion NgModel-3 -->
|
<!-- #enddocregion NgModel-3 -->
|
||||||
(ngModelChange) = "...firstName=$event"
|
(ngModelChange) = "...firstName=$event"
|
||||||
<br>
|
<br>
|
||||||
<!-- #docregion NgModel-4 -->
|
<!-- #docregion NgModel-4 -->
|
||||||
<input
|
<input
|
||||||
[ngModel]="currentHero.firstName"
|
[ngModel]="currentHero.firstName"
|
||||||
(ngModelChange)="setUpperCaseFirstName($event)">
|
(ngModelChange)="setUpperCaseFirstName($event)">
|
||||||
<!-- #enddocregion NgModel-4 -->
|
<!-- #enddocregion NgModel-4 -->
|
||||||
(ngModelChange) = "setUpperCaseFirstName($event)"
|
(ngModelChange) = "setUpperCaseFirstName($event)"
|
||||||
<br>
|
<br>
|
||||||
@ -443,7 +440,7 @@ bindon-ngModel
|
|||||||
<!-- #enddocregion NgIf-1 -->
|
<!-- #enddocregion NgIf-1 -->
|
||||||
|
|
||||||
<!-- #docregion NgIf-2 -->
|
<!-- #docregion NgIf-2 -->
|
||||||
<!-- not displayed because nullHero is false.
|
<!-- because of the ngIf guard
|
||||||
`nullHero.firstName` never has a chance to fail -->
|
`nullHero.firstName` never has a chance to fail -->
|
||||||
<div *ngIf="nullHero != null">Hello, {{nullHero.firstName}}</div>
|
<div *ngIf="nullHero != null">Hello, {{nullHero.firstName}}</div>
|
||||||
|
|
||||||
@ -487,33 +484,33 @@ bindon-ngModel
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="toe">
|
<div class="toe">
|
||||||
<div *ngIf="toeChoice == null">Pick a toe</div>
|
<div *ngIf="toeChoice == null">Pick a toe</div>
|
||||||
<div *ngIf="toeChoice != null">
|
<div *ngIf="toeChoice != null">
|
||||||
You picked ...
|
You picked ...
|
||||||
<!-- #docregion NgSwitch, NgSwitch-expanded -->
|
<!-- #docregion NgSwitch, NgSwitch-expanded -->
|
||||||
<span [ngSwitch]="toeChoice">
|
<span [ngSwitch]="toeChoice">
|
||||||
<!-- #enddocregion NgSwitch -->
|
<!-- #enddocregion NgSwitch -->
|
||||||
|
|
||||||
<!-- with *NgSwitch -->
|
<!-- with *NgSwitch -->
|
||||||
<!-- #docregion NgSwitch -->
|
<!-- #docregion NgSwitch -->
|
||||||
<span *ngSwitchWhen="'Eenie'">Eenie</span>
|
<span *ngSwitchWhen="'Eenie'">Eenie</span>
|
||||||
<span *ngSwitchWhen="'Meanie'">Meanie</span>
|
<span *ngSwitchWhen="'Meanie'">Meanie</span>
|
||||||
<span *ngSwitchWhen="'Miney'">Miney</span>
|
<span *ngSwitchWhen="'Miney'">Miney</span>
|
||||||
<span *ngSwitchWhen="'Moe'">Moe</span>
|
<span *ngSwitchWhen="'Moe'">Moe</span>
|
||||||
<span *ngSwitchDefault>other</span>
|
<span *ngSwitchDefault>other</span>
|
||||||
<!-- #enddocregion NgSwitch -->
|
<!-- #enddocregion NgSwitch -->
|
||||||
|
|
||||||
<!-- with <template> -->
|
<!-- with <template> -->
|
||||||
<template ngSwitchWhen="Eenie"><span>Eenie</span></template>
|
<template [ngSwitchWhen]="'Eenie'"><span>Eenie</span></template>
|
||||||
<template ngSwitchWhen="Meanie"><span>Meanie</span></template>
|
<template [ngSwitchWhen]="'Meanie'"><span>Meanie</span></template>
|
||||||
<template ngSwitchWhen="Miney"><span>Miney</span></template>
|
<template [ngSwitchWhen]="'Miney'"><span>Miney</span></template>
|
||||||
<template ngSwitchWhen="Moe"><span>Moe</span></template>
|
<template [ngSwitchWhen]="'Moe'"><span>Moe</span></template>
|
||||||
<template ngSwitchDefault><span>other</span></template>
|
<template ngSwitchDefault><span>other</span></template>
|
||||||
|
|
||||||
<!-- #docregion NgSwitch -->
|
<!-- #docregion NgSwitch -->
|
||||||
</span>
|
</span>
|
||||||
<!-- #enddocregion NgSwitch, NgSwitch-expanded -->
|
<!-- #enddocregion NgSwitch, NgSwitch-expanded -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
@ -620,7 +617,7 @@ bindon-ngModel
|
|||||||
<p><i>expand to <template></i></p>
|
<p><i>expand to <template></i></p>
|
||||||
<!-- #docregion Template-2 -->
|
<!-- #docregion Template-2 -->
|
||||||
<template [ngIf]="currentHero != null">
|
<template [ngIf]="currentHero != null">
|
||||||
<hero-detail [hero]="currentHero"></hero-detail>
|
<hero-detail [hero]="currentHero"></hero-detail>
|
||||||
</template>
|
</template>
|
||||||
<!-- #enddocregion Template-2 -->
|
<!-- #enddocregion Template-2 -->
|
||||||
|
|
||||||
@ -644,15 +641,15 @@ bindon-ngModel
|
|||||||
<!-- ngFor w/ hero-detail Component inside a template element -->
|
<!-- ngFor w/ hero-detail Component inside a template element -->
|
||||||
<!-- #docregion Template-4 -->
|
<!-- #docregion Template-4 -->
|
||||||
<template ngFor let-hero [ngForOf]="heroes" [ngForTrackBy]="trackByHeroes">
|
<template ngFor let-hero [ngForOf]="heroes" [ngForTrackBy]="trackByHeroes">
|
||||||
<hero-detail [hero]="hero"></hero-detail>
|
<hero-detail [hero]="hero"></hero-detail>
|
||||||
</template>
|
</template>
|
||||||
<!-- #enddocregion Template-4 -->
|
<!-- #enddocregion Template-4 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
|
||||||
<!-- template local variable -->
|
<!-- template reference variable -->
|
||||||
<hr><h2 id="local-vars">Template local variables</h2>
|
<hr><h2 id="ref-vars">Template reference variables</h2>
|
||||||
|
|
||||||
<!-- #docregion ref-phone -->
|
<!-- #docregion ref-phone -->
|
||||||
<!-- phone refers to the input element; pass its `value` to an event handler -->
|
<!-- phone refers to the input element; pass its `value` to an event handler -->
|
||||||
@ -672,7 +669,7 @@ bindon-ngModel
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<input class="form-control" required ngControl="firstName"
|
<input class="form-control" required ngControl="firstName"
|
||||||
[(ngModel)]="currentHero.firstName">
|
[(ngModel)]="currentHero.firstName">
|
||||||
</div>
|
</div>
|
||||||
<!-- #docregion ref-form-a -->
|
<!-- #docregion ref-form-a -->
|
||||||
<button type="submit" [disabled]="!theForm.form.valid">Submit</button>
|
<button type="submit" [disabled]="!theForm.form.valid">Submit</button>
|
||||||
@ -682,7 +679,7 @@ bindon-ngModel
|
|||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<!-- btn refers to the button element; show its disabled state -->
|
<!-- btn refers to the button element; show its disabled state -->
|
||||||
<button #btn disabled [textContent]="'disabled by attribute: ' + btn.disabled.toString()"></button>
|
<button #btn disabled [innerHTML]="'disabled by attribute: ' + btn.disabled.toString()"></button>
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
|
||||||
@ -708,13 +705,15 @@ bindon-ngModel
|
|||||||
<hr><h2 id="pipes">Pipes</h2>
|
<hr><h2 id="pipes">Pipes</h2>
|
||||||
|
|
||||||
<!-- #docregion pipes-1 -->
|
<!-- #docregion pipes-1 -->
|
||||||
<!-- Force title to uppercase -->
|
<div>Title through uppercase pipe: {{title | uppercase}}</div>
|
||||||
<div>{{ title | uppercase }}</div>
|
|
||||||
<!-- #enddocregion pipes-1 -->
|
<!-- #enddocregion pipes-1 -->
|
||||||
|
|
||||||
<!-- #docregion pipes-2 -->
|
<!-- #docregion pipes-2 -->
|
||||||
<!-- Pipe chaining: force title to uppercase, then to lowercase -->
|
<!-- Pipe chaining: convert title to uppercase, then to lowercase -->
|
||||||
<div>{{ title | uppercase | lowercase }}</div>
|
<div>
|
||||||
|
Title through a pipe chain:
|
||||||
|
{{title | uppercase | lowercase}}
|
||||||
|
</div>
|
||||||
<!-- #enddocregion pipes-2 -->
|
<!-- #enddocregion pipes-2 -->
|
||||||
|
|
||||||
<!-- #docregion pipes-3 -->
|
<!-- #docregion pipes-3 -->
|
||||||
@ -723,16 +722,14 @@ bindon-ngModel
|
|||||||
<!-- #enddocregion pipes-3 -->
|
<!-- #enddocregion pipes-3 -->
|
||||||
|
|
||||||
<!-- #docregion pipes-json -->
|
<!-- #docregion pipes-json -->
|
||||||
<!-- We don't suggest using json for debugging; you'd probably use toString() instead.
|
<div>{{currentHero}}</div>
|
||||||
Is there a good use for the json pipe in Dart? -->
|
|
||||||
<!--<div>{{currentHero | json}}</div>-->
|
|
||||||
<!-- #enddocregion pipes-json -->
|
<!-- #enddocregion pipes-json -->
|
||||||
|
|
||||||
<div>Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}</div>
|
<div>Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- pipe price to USD and display the $ symbol -->
|
<!-- pipe price to USD and display the $ symbol -->
|
||||||
<label>Price: </label>{{product['price'] | currency:'$'}}
|
<label>Price: </label>{{product['price'] | currency:'USD':false}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
@ -742,7 +739,7 @@ bindon-ngModel
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- #docregion safe-1 -->
|
<!-- #docregion safe-1 -->
|
||||||
The title is {{ title }}
|
The title is {{title}}
|
||||||
<!-- #enddocregion safe-1 -->
|
<!-- #enddocregion safe-1 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -759,11 +756,10 @@ bindon-ngModel
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
The null hero's name is {{nullHero.firstName}}
|
The null hero's name is {{nullHero.firstName}}
|
||||||
|
|
||||||
See console log:
|
See console log:
|
||||||
EXCEPTION: The null object does not have a getter 'firstName'.
|
EXCEPTION: The null object does not have a getter 'firstName'.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -784,19 +780,16 @@ The null hero's name is {{nullHero.firstName}}
|
|||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
|
||||||
<!-- Todo: discuss this in the Style binding section -->
|
<!-- TODO: discuss this in the Style binding section -->
|
||||||
<!-- enums in bindings -->
|
<!-- enums in bindings -->
|
||||||
|
|
||||||
<hr><h2 id="enums">Enums in binding</h2>
|
<hr><h2 id="enums">Enums in binding</h2>
|
||||||
|
|
||||||
<!--<p>The name of the Color.red enum is {{color}}</p>-->
|
<p>
|
||||||
<p>The current color number is {{color}}</p>
|
<!-- #docregion enums -->
|
||||||
<p><button [style.color]="color.toString()" (click)="colorToggle()">Enum Toggle</button>
|
The name of the Color.red enum is {{colorRed}}.<br>
|
||||||
|
The current color is {{color}} and its index is {{color.index}}.<br>
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<button [style.color]="color.toString()" (click)="colorToggle()">Enum Toggle</button>
|
||||||
|
<!-- #enddocregion enums -->
|
||||||
<!-- #docregion my-first-app -->
|
</p>
|
||||||
<h3>My First Angular Application</h3>
|
|
||||||
<!-- #enddocregion my-first-app -->
|
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
@ -52,13 +52,13 @@
|
|||||||
<!-- #enddocregion title+image -->
|
<!-- #enddocregion title+image -->
|
||||||
|
|
||||||
<!-- #docregion sum-1 -->
|
<!-- #docregion sum-1 -->
|
||||||
<!-- "The sum of 1 + 1 is 2" -->
|
<!-- "The sum of 1 + 1 is 2" -->
|
||||||
<p>The sum of 1 + 1 is {{1 + 1}}</p>
|
<p>The sum of 1 + 1 is {{1 + 1}}</p>
|
||||||
<!-- #enddocregion sum-1 -->
|
<!-- #enddocregion sum-1 -->
|
||||||
|
|
||||||
<!-- #docregion sum-2 -->
|
<!-- #docregion sum-2 -->
|
||||||
<!-- "The sum of 1 + 1 is not 4" -->
|
<!-- "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 -->
|
<!-- #enddocregion sum-2 -->
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
@ -66,8 +66,8 @@
|
|||||||
<!-- New Mental Model -->
|
<!-- New Mental Model -->
|
||||||
<hr><h2 id="mental-model">New Mental Model</h2>
|
<hr><h2 id="mental-model">New Mental Model</h2>
|
||||||
|
|
||||||
<!--<img src="http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png">-->
|
<!--<img src="http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png">-->
|
||||||
<!-- Public Domain terms of use: http://www.wpclipart.com/terms.html -->
|
<!-- Public Domain terms of use: http://www.wpclipart.com/terms.html -->
|
||||||
<!-- #docregion img+button -->
|
<!-- #docregion img+button -->
|
||||||
<div class="special">Mental Model</div>
|
<div class="special">Mental Model</div>
|
||||||
<img src="images/hero.png">
|
<img src="images/hero.png">
|
||||||
@ -184,13 +184,14 @@ button</button>
|
|||||||
<!-- #enddocregion property-binding-5 -->
|
<!-- #enddocregion property-binding-5 -->
|
||||||
|
|
||||||
<!-- #docregion property-binding-6 -->
|
<!-- #docregion property-binding-6 -->
|
||||||
<!--
|
<!-- ERROR: HeroDetailComponent.hero expects a
|
||||||
BAD!
|
Hero object, not the string "currentHero" -->
|
||||||
HeroDetailComponent.hero expects a Hero object,
|
|
||||||
not the string "currentHero"
|
|
||||||
-->
|
|
||||||
<hero-detail hero="currentHero"></hero-detail>
|
|
||||||
<!-- #enddocregion property-binding-6 -->
|
<!-- #enddocregion property-binding-6 -->
|
||||||
|
<div *ngIf="false">
|
||||||
|
<!-- #docregion property-binding-6 -->
|
||||||
|
<hero-detail hero="currentHero"></hero-detail>
|
||||||
|
<!-- #enddocregion property-binding-6 -->
|
||||||
|
</div>
|
||||||
<!-- #docregion property-binding-7 -->
|
<!-- #docregion property-binding-7 -->
|
||||||
<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>
|
<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>
|
||||||
<!-- #enddocregion property-binding-7 -->
|
<!-- #enddocregion property-binding-7 -->
|
||||||
@ -199,8 +200,8 @@ button</button>
|
|||||||
Interpolated: <img src="{{heroImageUrl}}"><br>
|
Interpolated: <img src="{{heroImageUrl}}"><br>
|
||||||
Property bound: <img [src]="heroImageUrl">
|
Property bound: <img [src]="heroImageUrl">
|
||||||
|
|
||||||
<div>The interpolated title is {{title}}</div>
|
<div>The interpolated title is {{title}}</div>
|
||||||
<div [innerHTML]="'The [innerHTML] title is '+title"></div>
|
<div [innerHTML]="'The [innerHTML] title is '+title"></div>
|
||||||
<!-- #enddocregion property-binding-vs-interpolation -->
|
<!-- #enddocregion property-binding-vs-interpolation -->
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
@ -278,13 +279,13 @@ Property bound: <img [src]="heroImageUrl">
|
|||||||
<hr><h2 id="style-binding">Style Binding</h2>
|
<hr><h2 id="style-binding">Style Binding</h2>
|
||||||
|
|
||||||
<!-- #docregion style-binding-1 -->
|
<!-- #docregion style-binding-1 -->
|
||||||
<button [style.color] = "isSpecial ? 'red' : 'green'">Red</button>
|
<button [style.color] = "isSpecial ? 'red': 'green'">Red</button>
|
||||||
<button [style.backgroundColor]="canSave ?'cyan' : 'grey'" >Save</button>
|
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
|
||||||
<!-- #enddocregion style-binding-1 -->
|
<!-- #enddocregion style-binding-1 -->
|
||||||
|
|
||||||
<!-- #docregion style-binding-2 -->
|
<!-- #docregion style-binding-2 -->
|
||||||
<button [style.fontSize.em]="isSpecial ? 3 : 1" >Big</button>
|
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
|
||||||
<button [style.fontSize.%]="!isSpecial ? 150 : 50" >Small</button>
|
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
|
||||||
<!-- #enddocregion style-binding-2 -->
|
<!-- #enddocregion style-binding-2 -->
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
@ -393,7 +394,7 @@ bindon-ngModel
|
|||||||
<div [ngClass]="setClasses()">This div is saveable and special</div>
|
<div [ngClass]="setClasses()">This div is saveable and special</div>
|
||||||
<!-- #enddocregion NgClass-1 -->
|
<!-- #enddocregion NgClass-1 -->
|
||||||
<div [ngClass]="setClasses()" #classDiv>
|
<div [ngClass]="setClasses()" #classDiv>
|
||||||
After setClasses(), the classes are "{{classDiv.className}}"
|
After setClasses(), the classes are "{{classDiv.className}}"
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- not used in chapter -->
|
<!-- not used in chapter -->
|
||||||
@ -409,8 +410,8 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<hr><h2 id="ngStyle">NgStyle Binding</h2>
|
<hr><h2 id="ngStyle">NgStyle Binding</h2>
|
||||||
|
|
||||||
<!-- #docregion NgStyle-1 -->
|
<!-- #docregion NgStyle-1 -->
|
||||||
<div [style.fontSize]="isSpecial ? 'x-large' : 'smaller'" >
|
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
|
||||||
This div is x-large
|
This div is x-large.
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion NgStyle-1 -->
|
<!-- #enddocregion NgStyle-1 -->
|
||||||
|
|
||||||
@ -418,12 +419,12 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<p>setStyles returns {{setStyles() | json}}</p>
|
<p>setStyles returns {{setStyles() | json}}</p>
|
||||||
<!-- #docregion NgStyle-2 -->
|
<!-- #docregion NgStyle-2 -->
|
||||||
<div [ngStyle]="setStyles()">
|
<div [ngStyle]="setStyles()">
|
||||||
This div is italic, normal weight, and extra large (24px)
|
This div is italic, normal weight, and extra large (24px).
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion NgStyle-2 -->
|
<!-- #enddocregion NgStyle-2 -->
|
||||||
<p>After setStyles(), the DOM confirms that the styles are
|
<p>After setStyles(), the DOM confirms that the styles are
|
||||||
<span [ngStyle]="setStyles()" #styleDiv>
|
<span [ngStyle]="setStyles()" #styleDiv>
|
||||||
"{{getStyles(styleDiv)}}"
|
{{getStyles(styleDiv)}}
|
||||||
</span>.
|
</span>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -439,7 +440,7 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<!-- #enddocregion NgIf-1 -->
|
<!-- #enddocregion NgIf-1 -->
|
||||||
|
|
||||||
<!-- #docregion NgIf-2 -->
|
<!-- #docregion NgIf-2 -->
|
||||||
<!-- not displayed because nullHero is falsey.
|
<!-- because of the ngIf guard
|
||||||
`nullHero.firstName` never has a chance to fail -->
|
`nullHero.firstName` never has a chance to fail -->
|
||||||
<div *ngIf="nullHero">Hello, {{nullHero.firstName}}</div>
|
<div *ngIf="nullHero">Hello, {{nullHero.firstName}}</div>
|
||||||
|
|
||||||
@ -603,22 +604,22 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<hr><h2 id="star-prefix">* prefix and <template></h2>
|
<hr><h2 id="star-prefix">* prefix and <template></h2>
|
||||||
|
|
||||||
<h3>*ngIf expansion</h3>
|
<h3>*ngIf expansion</h3>
|
||||||
<p><i>*ngIf</i></p>
|
<p><i>*ngIf</i></p>
|
||||||
<!-- #docregion Template-1 -->
|
<!-- #docregion Template-1 -->
|
||||||
<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>
|
<hero-detail *ngIf="currentHero" [hero]="currentHero"></hero-detail>
|
||||||
<!-- #enddocregion Template-1 -->
|
<!-- #enddocregion Template-1 -->
|
||||||
|
|
||||||
<p><i>expand to template = "..."</i></p>
|
<p><i>expand to template = "..."</i></p>
|
||||||
<!-- #docregion Template-2a -->
|
<!-- #docregion Template-2a -->
|
||||||
<hero-detail template="ngIf:currentHero" [hero]="currentHero"></hero-detail>
|
<hero-detail template="ngIf:currentHero" [hero]="currentHero"></hero-detail>
|
||||||
<!-- #enddocregion Template-2a -->
|
<!-- #enddocregion Template-2a -->
|
||||||
|
|
||||||
<p><i>expand to <template></i></p>
|
<p><i>expand to <template></i></p>
|
||||||
<!-- #docregion Template-2 -->
|
<!-- #docregion Template-2 -->
|
||||||
<template [ngIf]="currentHero">
|
<template [ngIf]="currentHero">
|
||||||
<hero-detail [hero]="currentHero"></hero-detail>
|
<hero-detail [hero]="currentHero"></hero-detail>
|
||||||
</template>
|
</template>
|
||||||
<!-- #enddocregion Template-2 -->
|
<!-- #enddocregion Template-2 -->
|
||||||
|
|
||||||
<h3>*ngFor expansion</h3>
|
<h3>*ngFor expansion</h3>
|
||||||
<p><i>*ngFor</i></p>
|
<p><i>*ngFor</i></p>
|
||||||
@ -658,7 +659,7 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<!-- fax refers to the input element; pass its `value` to an event handler -->
|
<!-- fax refers to the input element; pass its `value` to an event handler -->
|
||||||
<input ref-fax placeholder="fax number">
|
<input ref-fax placeholder="fax number">
|
||||||
<button (click)="callFax(fax.value)">Fax</button>
|
<button (click)="callFax(fax.value)">Fax</button>
|
||||||
<!-- #enddocregion ref-phone -->
|
<!-- #enddocregion ref-phone -->
|
||||||
|
|
||||||
<h4>Example Form</h4>
|
<h4>Example Form</h4>
|
||||||
<!-- #docregion ref-form -->
|
<!-- #docregion ref-form -->
|
||||||
@ -704,13 +705,15 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<hr><h2 id="pipes">Pipes</h2>
|
<hr><h2 id="pipes">Pipes</h2>
|
||||||
|
|
||||||
<!-- #docregion pipes-1 -->
|
<!-- #docregion pipes-1 -->
|
||||||
<!-- Force title to uppercase -->
|
<div>Title through uppercase pipe: {{title | uppercase}}</div>
|
||||||
<div>{{ title | uppercase }}</div>
|
|
||||||
<!-- #enddocregion pipes-1 -->
|
<!-- #enddocregion pipes-1 -->
|
||||||
|
|
||||||
<!-- #docregion pipes-2 -->
|
<!-- #docregion pipes-2 -->
|
||||||
<!-- Pipe chaining: force title to uppercase, then to lowercase -->
|
<!-- Pipe chaining: convert title to uppercase, then to lowercase -->
|
||||||
<div>{{ title | uppercase | lowercase }}</div>
|
<div>
|
||||||
|
Title through a pipe chain:
|
||||||
|
{{title | uppercase | lowercase}}
|
||||||
|
</div>
|
||||||
<!-- #enddocregion pipes-2 -->
|
<!-- #enddocregion pipes-2 -->
|
||||||
|
|
||||||
<!-- #docregion pipes-3 -->
|
<!-- #docregion pipes-3 -->
|
||||||
@ -720,16 +723,8 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
|
|
||||||
<!-- #docregion pipes-json -->
|
<!-- #docregion pipes-json -->
|
||||||
<div>{{currentHero | json}}</div>
|
<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 -->
|
<!-- #enddocregion pipes-json -->
|
||||||
|
|
||||||
|
|
||||||
<div>Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}</div>
|
<div>Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -743,29 +738,29 @@ After setClasses(), the classes are "{{classDiv.className}}"
|
|||||||
<hr><h2 id="safe-navigation-operator">Safe navigation operator <i>?.</i></h2>
|
<hr><h2 id="safe-navigation-operator">Safe navigation operator <i>?.</i></h2>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- #docregion safe-1 -->
|
<!-- #docregion safe-1 -->
|
||||||
The title is {{ title }}
|
The title is {{title}}
|
||||||
<!-- #enddocregion safe-1 -->
|
<!-- #enddocregion safe-1 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- #docregion safe-2 -->
|
<!-- #docregion safe-2 -->
|
||||||
The current hero's name is {{currentHero?.firstName}}
|
The current hero's name is {{currentHero?.firstName}}
|
||||||
<!-- #enddocregion safe-2 -->
|
<!-- #enddocregion safe-2 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- #docregion safe-3 -->
|
<!-- #docregion safe-3 -->
|
||||||
The current hero's name is {{currentHero.firstName}}
|
The current hero's name is {{currentHero.firstName}}
|
||||||
<!-- #enddocregion safe-3 -->
|
<!-- #enddocregion safe-3 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
The null hero's name is {{nullHero.firstName}}
|
The null hero's name is {{nullHero.firstName}}
|
||||||
|
|
||||||
See console log
|
See console log:
|
||||||
TypeError: Cannot read property 'firstName' of null in [null]
|
TypeError: Cannot read property 'firstName' of null in [null]
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- #docregion safe-4 -->
|
<!-- #docregion safe-4 -->
|
||||||
@ -780,27 +775,25 @@ The null hero's name is {{nullHero && nullHero.firstName}}
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<!-- #docregion safe-6 -->
|
<!-- #docregion safe-6 -->
|
||||||
<!-- No hero, no problem! -->
|
<!-- No hero, no problem! -->
|
||||||
The null hero's name is {{nullHero?.firstName}}
|
The null hero's name is {{nullHero?.firstName}}
|
||||||
<!-- #enddocregion safe-6 -->
|
<!-- #enddocregion safe-6 -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
|
||||||
<!-- Todo: discuss this in the Style binding section -->
|
<!-- TODO: discuss this in the Style binding section -->
|
||||||
<!-- enums in bindings -->
|
<!-- enums in bindings -->
|
||||||
<hr><h2 id="enums">Enums in binding</h2>
|
<hr><h2 id="enums">Enums in binding</h2>
|
||||||
|
|
||||||
<p>The name of the Color.Red enum is {{Color[Color.Red]}}</p>
|
<p>
|
||||||
<p>The current color number is {{color}}</p>
|
<!-- #docregion enums -->
|
||||||
<p><button [style.color]="Color[color]" (click)="colorToggle()">Enum Toggle</button>
|
The name of the Color.Red enum is {{Color[Color.Red]}}.<br>
|
||||||
|
The current color is {{Color[color]}} and its number is {{color}}.<br>
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<button [style.color]="Color[color]" (click)="colorToggle()">Enum Toggle</button>
|
||||||
|
<!-- #enddocregion enums -->
|
||||||
<!-- #docregion my-first-app -->
|
</p>
|
||||||
<h3>My First Angular Application</h3>
|
|
||||||
<!-- #enddocregion my-first-app -->
|
|
||||||
|
|
||||||
<a class="to-toc" href="#toc">top</a>
|
<a class="to-toc" href="#toc">top</a>
|
||||||
|
@ -77,6 +77,9 @@ export class AppComponent implements AfterViewInit, OnInit {
|
|||||||
heroImageUrl = 'images/hero.png';
|
heroImageUrl = 'images/hero.png';
|
||||||
|
|
||||||
//iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png';
|
//iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png';
|
||||||
|
clicked = '';
|
||||||
|
clickMessage = '';
|
||||||
|
clickMessage2 = '';
|
||||||
iconUrl = 'images/ng-logo.png';
|
iconUrl = 'images/ng-logo.png';
|
||||||
isActive = false;
|
isActive = false;
|
||||||
isSpecial = true;
|
isSpecial = true;
|
||||||
|
@ -3,6 +3,7 @@ include ../../../_includes/_util-fns
|
|||||||
//- See the _util-fns file included above for a description of the use of these variables.
|
//- See the _util-fns file included above for a description of the use of these variables.
|
||||||
- var _docsFor = 'dart';
|
- var _docsFor = 'dart';
|
||||||
- var _decorator = 'annotation';
|
- var _decorator = 'annotation';
|
||||||
|
- var _Array = 'List';
|
||||||
- var _array = 'list';
|
- var _array = 'list';
|
||||||
- var _an_array = 'a list'; //- Deprecate now that we have the articles
|
- var _an_array = 'a list'; //- Deprecate now that we have the articles
|
||||||
- var _a = 'an';
|
- var _a = 'an';
|
||||||
@ -12,6 +13,8 @@ include ../../../_includes/_util-fns
|
|||||||
- var _Promise = 'Future';
|
- var _Promise = 'Future';
|
||||||
- var _Observable = 'Stream';
|
- var _Observable = 'Stream';
|
||||||
- var _liveLink = 'sample repo';
|
- var _liveLink = 'sample repo';
|
||||||
|
- var _truthy = 'true';
|
||||||
|
- var _falsey = 'false';
|
||||||
|
|
||||||
mixin liveExampleLink(linkText, exampleUrlPartName)
|
mixin liveExampleLink(linkText, exampleUrlPartName)
|
||||||
- var text = linkText || 'live example';
|
- var text = linkText || 'live example';
|
||||||
|
@ -1,407 +1,128 @@
|
|||||||
include ../_util-fns
|
extends ../../../ts/latest/guide/template-syntax.jade
|
||||||
|
|
||||||
+includeShared('{ts}', 'intro')
|
block includes
|
||||||
|
include ../_util-fns
|
||||||
|
- var _JavaScript = 'Dart';
|
||||||
|
- var __chaining_op = '<code>;</code>';
|
||||||
|
- var __new_op = '<code>new</code> or <code>const</code>';
|
||||||
|
- var mapApiRef = 'https://api.dartlang.org/stable/1.16.0/dart-core/Map-class.html';
|
||||||
|
- var __objectAsMap = '<b><a href="' + mapApiRef + '">Map</a></b>'
|
||||||
|
|
||||||
:marked
|
block notable-differences
|
||||||
The complete source code for the example app in this chapter is
|
|
||||||
[in GitHub](https://github.com/angular/angular.io/tree/master/public/docs/_examples/template-syntax/dart).
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'html-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'my-first-app')(format=".")
|
|
||||||
+includeShared('{ts}', 'html-2')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'interpolation-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'first-interpolation')(format=".")
|
|
||||||
+includeShared('{ts}', 'interpolation-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'title+image')(format=".")
|
|
||||||
+includeShared('{ts}', 'interpolation-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'sum-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'interpolation-4')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'sum-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'interpolation-5')
|
|
||||||
|
|
||||||
+includeShared('{ts}', '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:
|
|
||||||
|
|
||||||
* assignments (`=`, `+=`, `-=`, ...)
|
|
||||||
* creating instances using `new` or `const`
|
|
||||||
* increment and decrement (`++` and `--`)
|
|
||||||
|
|
||||||
Other notable differences from Dart syntax include:
|
|
||||||
|
|
||||||
* no support for Dart string interpolation; for example,
|
|
||||||
instead of `"'The title is $title'"`, you must use
|
|
||||||
`"'The title is ' + title"`
|
|
||||||
* no support for the bitwise operators `|` and `&`
|
|
||||||
* new [template expression operators](#expression-operators), such as `|`
|
|
||||||
+includeShared('{ts}', 'template-expressions-context')
|
|
||||||
+includeShared('{ts}', '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
|
:marked
|
||||||
Arrays in JavaScript correspond to lists in Dart
|
* no support for Dart string interpolation; for example,
|
||||||
(instances of the `List` class).
|
instead of `"'The title is $title'"`, you must use
|
||||||
This chapter uses _array_ and _list_ interchangeably.
|
`"'The title is ' + title"`
|
||||||
For more information, see
|
* no support for the bitwise operators `|` and `&`
|
||||||
[Lists](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#lists)
|
* new [template expression operators](#expression-operators), such as `|`
|
||||||
in the [Dart language tour](https://www.dartlang.org/docs/dart-up-and-running/ch02.html).
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'template-statements-1')
|
block template-expressions-cannot
|
||||||
: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 (`;`).
|
|
||||||
|
|
||||||
However, certain Dart syntax is not allowed:
|
|
||||||
* the `new` and `const` keywords
|
|
||||||
* increment and decrement operators, `++` and `--`
|
|
||||||
* operator assignment, such as `+=` and `-=`
|
|
||||||
* the operators `|` and `&` (neither for bitwise operations
|
|
||||||
nor for the Angular [pipe operator](#the-pipe-operator-))
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'template-statements-3')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'binding-syntax-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'img+button')(format=".")
|
|
||||||
+includeShared('{ts}', 'binding-syntax-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'hero-detail-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'binding-syntax-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'disabled-button-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'binding-syntax-4')
|
|
||||||
+includeShared('{ts}', 'binding-syntax-attribute-vs-property')
|
|
||||||
+includeShared('{ts}', 'binding-syntax-5')
|
|
||||||
+includeShared('{ts}', 'binding-syntax-world-without-attributes')
|
|
||||||
+includeShared('{ts}', '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}', 'binding-syntax-end')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'property-binding-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-4')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-5')
|
|
||||||
+includeShared('{ts}', 'property-binding-6')
|
|
||||||
+includeShared('{ts}', 'property-binding-7')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-8')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-5')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-9')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-10')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-11')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-6')(format=".")
|
|
||||||
.callout.is-helpful
|
|
||||||
header Dart difference: Type exceptions
|
|
||||||
:marked
|
:marked
|
||||||
In checked mode, uncommenting the `<hero-detail>` element above causes a type exception,
|
Perhaps more surprising, template expressions can’t refer to static
|
||||||
because `String` isn't a subtype of `Hero`.
|
properties, nor to top-level variables or functions, such as `window` or
|
||||||
For information on checked mode, see [Important concepts](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#important-concepts)
|
`document` from `dart:html`. They can’t directly call `print` or functions
|
||||||
in the Dart language tour.
|
imported from `dart:math`. They are restricted to referencing members of
|
||||||
+includeShared('{ts}', 'property-binding-12')
|
the expression context.
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-7')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-13')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-vs-interpolation')(format=".")
|
|
||||||
+includeShared('{ts}', 'property-binding-14')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'other-bindings-1')
|
block statement-context
|
||||||
+includeShared('{ts}', 'other-bindings-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-colspan')(format=".")
|
|
||||||
+includeShared('{ts}', 'other-bindings-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-aria')(format=".")
|
|
||||||
+includeShared('{ts}', 'other-bindings-class-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'other-bindings-class-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-2')(format=".")
|
|
||||||
//
|
|
||||||
+includeShared('{ts}', '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}', 'other-bindings-class-4')
|
|
||||||
+includeShared('{ts}', 'other-bindings-style-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'other-bindings-style-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'other-bindings-style-3')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'event-binding-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-4')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-3')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-5')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-6')
|
|
||||||
+makeExample('template-syntax/dart/lib/hero_detail_component.dart',
|
|
||||||
'template-1', 'HeroDetailComponent.ts (template)')(format=".")
|
|
||||||
+makeExample('template-syntax/dart/lib/hero_detail_component.dart',
|
|
||||||
'deleteRequest', 'HeroDetailComponent.ts (delete logic)')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-7')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-to-component')(format=".")
|
|
||||||
+includeShared('{ts}', 'event-binding-8')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'ngModel-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'ngModel-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'ngModel-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".")
|
|
||||||
+includeShared('{ts}', 'ngModel-4')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-3')(format=".")
|
|
||||||
+includeShared('{ts}', 'ngModel-5')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'ngModel-6')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-4')(format=".")
|
|
||||||
+includeShared('{ts}', 'ngModel-7')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'directives-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-2')
|
|
||||||
+includeShared('{ts}', 'directives-ngClass-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-3a')(format=".")
|
|
||||||
+includeShared('{ts}', '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}', 'directives-ngClass-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgClass-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngStyle-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngStyle-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.dart', 'setStyles')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngStyle-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-2')(format=".")
|
|
||||||
//
|
|
||||||
+includeShared('{ts}', '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}', 'directives-ngIf-2')
|
|
||||||
//
|
|
||||||
+includeShared('{ts}', '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
|
:marked
|
||||||
In checked mode, Dart expects Boolean values
|
Template statements can’t refer to static properties on the class, nor to
|
||||||
(those with type `bool`) to be either `true` or `false`.
|
top-level variables or functions, such as `window` or `document` from
|
||||||
Even in production mode, the only value Dart treats as `true` is
|
`dart:html`. They can’t directly call `print` or functions imported from
|
||||||
the value `true`; all other values are `false`.
|
`dart:math`.
|
||||||
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
|
block dart-type-exceptions
|
||||||
true/false problems. For example, forgetting the `!= null`
|
.callout.is-helpful
|
||||||
can lead to exceptions in checked mode, such as
|
header Dart difference: Type exceptions
|
||||||
"EXCEPTION: type 'Hero' is not a subtype of type 'bool' of 'boolean expression'".
|
:marked
|
||||||
For more information, see
|
In checked mode, if the template expression result type and the target
|
||||||
[Booleans](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#booleans)
|
property type are not assignment compatible, then a type exception will
|
||||||
in the [Dart language tour](https://www.dartlang.org/docs/dart-up-and-running/ch02.html).
|
be thrown.
|
||||||
+includeShared('{ts}', 'directives-ngIf-4')
|
For information on checked mode, see [Important concepts](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#important-concepts)
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-3')(format=".")
|
in the Dart language tour.
|
||||||
+includeShared('{ts}', 'directives-ngIf-5')
|
|
||||||
+includeShared('{ts}', 'directives-ngSwitch-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgSwitch')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngSwitch-2')
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-3')
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-4')
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-5')
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-6')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-3')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngFor-7')
|
|
||||||
+includeShared('{ts}', 'directives-ngForTrackBy-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.dart', 'trackByHeroes')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngForTrackBy-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgForTrackBy-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'directives-ngForTrackBy-3')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'star-template')
|
block dart-type-exception-example
|
||||||
+includeShared('{ts}', 'star-template-ngIf-1')
|
.callout.is-helpful
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-1')(format=".")
|
header Dart difference: Type exception example
|
||||||
+includeShared('{ts}', 'star-template-ngIf-2a')
|
:marked
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-2a')(format=".")
|
In checked mode, the code above will result in a type exception:
|
||||||
+includeShared('{ts}', 'star-template-ngIf-2')
|
`String` isn't a subtype of `Hero`.
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'star-template-ngIf-3')
|
block dart-class-binding-bug
|
||||||
// Changed from RED to ORANGE, since this isn't so dire a situation in Dart.
|
.callout.is-helpful
|
||||||
.callout.is-important
|
header Angular Issue #6901
|
||||||
header Remember the brackets!
|
:marked
|
||||||
|
Issue [#6901][6901] prevents us from using `[class]`. As is illustrated
|
||||||
|
above, in the meantime we can achieve the same effect by binding to
|
||||||
|
`className`.
|
||||||
|
|
||||||
|
[6901]: http://github.com/angular/angular/issues/6901
|
||||||
|
|
||||||
|
block style-property-name-dart-diff
|
||||||
|
.callout.is-helpful
|
||||||
|
header Dart difference: Style property names
|
||||||
|
:marked
|
||||||
|
While [camelCase](glossary.html#camelcase) and
|
||||||
|
[dash-case](glossary.html#dash-case) style property naming schemes are
|
||||||
|
equivalent in Angular Dart, only dash-case names are recognized by the
|
||||||
|
`dart:html` [CssStyleDeclaration][CssSD] methods `getPropertyValue()`
|
||||||
|
and `setProperty()`. Hence, we recommend only using dash-case for style
|
||||||
|
property names.
|
||||||
|
|
||||||
|
[CssSD]: https://api.dartlang.org/stable/1.16.1/dart-html/CssStyleDeclaration-class.html
|
||||||
|
|
||||||
|
|
||||||
|
block dart-no-truthy-falsey
|
||||||
|
.callout.is-helpful
|
||||||
|
header Dart difference: No truthy/falsey 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 exceptions in checked mode, such as
|
||||||
|
"EXCEPTION: type 'Hero' is not a subtype of type 'bool' of 'boolean expression'".
|
||||||
|
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).
|
||||||
|
|
||||||
|
block remember-the-brackets
|
||||||
|
//- 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`.
|
||||||
|
|
||||||
|
block dart-safe-nav-op
|
||||||
|
.callout.is-helpful
|
||||||
|
header Dart difference: ?. is a Dart operator
|
||||||
|
:marked
|
||||||
|
The safe navigation operator (`?.`) is part of the Dart language.
|
||||||
|
It's considered a template expression operator because
|
||||||
|
Angular 2 supports `?.` even in TypeScript and JavaScript apps.
|
||||||
|
|
||||||
|
block json-pipe
|
||||||
|
//- TODO: explain alternative in Dart
|
||||||
|
//- {{ e | json }} --> {{ e }}
|
||||||
|
//- which causes the object's toString() method to be invoked.
|
||||||
|
//- Of course the `json` pipe can be used if the instance supports
|
||||||
|
//- JSON encoding.
|
||||||
|
|
||||||
|
block null-deref-example
|
||||||
:marked
|
:marked
|
||||||
Don’t make the mistake of writing `ngIf="currentHero"`!
|
Dart throws an exception, and so does Angular:
|
||||||
That syntax assigns the *string* value "currentHero" to `ngIf`,
|
code-example(format="nocode").
|
||||||
which won't work because `ngIf` expects a bool.
|
EXCEPTION: The null object does not have a getter 'firstName'.
|
||||||
+includeShared('{ts}', 'star-template-ngSwitch-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'NgSwitch-expanded')(format=".")
|
|
||||||
+includeShared('{ts}', 'star-template-ngSwitch-2')
|
|
||||||
+includeShared('{ts}', 'star-template-ngFor-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-3a')(format=".")
|
|
||||||
+includeShared('{ts}', 'star-template-ngFor-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-3')(format=".")
|
|
||||||
+includeShared('{ts}', 'star-template-ngFor-3')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'Template-4')(format=".")
|
|
||||||
+includeShared('{ts}', 'star-template-ngFor-4')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'ref-vars')
|
block safe-op-alt
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'ref-phone')(format=".")
|
//- N/A
|
||||||
+includeShared('{ts}', 'ref-vars-value')
|
|
||||||
+includeShared('{ts}', 'ref-vars-form-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'ref-form')(format=".")
|
|
||||||
+includeShared('{ts}', 'ref-vars-form-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'ref-form-a')(format=".")
|
|
||||||
+includeShared('{ts}', 'ref-vars-form-3')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'inputs-outputs-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'io-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'inputs-outputs-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'io-2')(format=".")
|
|
||||||
+includeShared('{ts}', '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}', 'inputs-outputs-4')
|
|
||||||
+includeShared('{ts}', 'inputs-outputs-5')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'my-click')(format=".")
|
|
||||||
+includeShared('{ts}', '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 _safe navigation operator_.
|
|
||||||
.callout.is-helpful
|
|
||||||
header Dart difference: ?. is a Dart operator
|
|
||||||
:marked
|
|
||||||
The safe navigation 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}', 'expression-operators-pipe-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'pipes-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'expression-operators-pipe-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'pipes-2')(format=".")
|
|
||||||
+includeShared('{ts}', '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}', 'expression-operators-pipe-4')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'pipes-json')(format=".")
|
|
||||||
+includeShared('{ts}', 'expression-operators-safe-1')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'safe-2')(format=".")
|
|
||||||
+includeShared('{ts}', 'expression-operators-safe-2')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'safe-1')(format=".")
|
|
||||||
+includeShared('{ts}', 'expression-operators-safe-3')
|
|
||||||
// +includeShared('{ts}', 'expression-operators-safe-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}', 'expression-operators-safe-5')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'safe-4')(format=".")
|
|
||||||
|
|
||||||
//
|
|
||||||
NOTE: Intentionally skip ugly null checking you wouldn't do in Dart.
|
|
||||||
That means skipping the shared sections 'expression-operators-safe-6' & 7,
|
|
||||||
plus the example 'safe-5'.
|
|
||||||
: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}', 'expression-operators-safe-8')
|
|
||||||
+makeExample('template-syntax/dart/lib/app_component.html', 'safe-6')(format=".")
|
|
||||||
+includeShared('{ts}', 'expression-operators-safe-9')
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'summary')
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user