From a664f462313237a18c668b57d844b045992704c0 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 25 May 2016 15:09:45 -0700 Subject: [PATCH] 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 --- public/_includes/_util-fns.jade | 8 +- .../template-syntax/dart/example-config.json | 0 .../dart/lib/app_component.dart | 18 +- .../dart/lib/app_component.html | 135 +++-- .../template-syntax/ts/app/app.component.html | 145 +++-- .../template-syntax/ts/app/app.component.ts | 3 + public/docs/dart/latest/_util-fns.jade | 3 + .../dart/latest/guide/template-syntax.jade | 513 ++++-------------- .../docs/ts/latest/guide/template-syntax.jade | 510 ++++++----------- 9 files changed, 433 insertions(+), 902 deletions(-) create mode 100644 public/docs/_examples/template-syntax/dart/example-config.json diff --git a/public/_includes/_util-fns.jade b/public/_includes/_util-fns.jade index 550330210c..5b46d869bb 100644 --- a/public/_includes/_util-fns.jade +++ b/public/_includes/_util-fns.jade @@ -21,6 +21,7 @@ - var _an = 'an'; //- TS arrays vs. Dart lists +- var _Array = 'Array'; - var _array = 'array'; //- Deprecate now that we have the articles _a and _an - var _an_array = 'an array'; @@ -32,6 +33,9 @@ //- Location of sample code - var _liveLink = 'live link'; +//- Other +- var _truthy = 'truthy'; +- var _falsey = 'falsey'; //- Used to prefix identifiers that are private. In Dart this will be '_'. - var _priv = ''; @@ -39,8 +43,8 @@ //- Use to conditionally include the block that follows +ifDocsFor(...). //- Generally favor use of Jade named blocks instead. ifDocsFor is convenient //- for prose that should appear only in one language version. -mixin ifDocsFor(lang) - if _docsFor.toLowerCase() === lang.toLowerCase() +mixin ifDocsFor(langPattern) + if _docsFor.toLowerCase().match(langPattern.toLowerCase()) block //- Use to map inlined (prose) TS paths into, say, Dart paths via the diff --git a/public/docs/_examples/template-syntax/dart/example-config.json b/public/docs/_examples/template-syntax/dart/example-config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.dart b/public/docs/_examples/template-syntax/dart/lib/app_component.dart index be36d6c38d..6d9199c175 100644 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.dart +++ b/public/docs/_examples/template-syntax/dart/lib/app_component.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:html'; import 'package:angular2/core.dart'; +import 'package:angular2/common.dart'; import 'hero.dart'; import 'hero_detail_component.dart'; @@ -40,7 +41,9 @@ class AppComponent implements OnInit, AfterViewInit { bool isSpecial = true; bool isUnchanged = true; bool isSelected = false; + final Color colorRed = Color.red; Color color = Color.red; + var colorEnum = Color; List heroes; Hero currentHero; @@ -56,7 +59,7 @@ class AppComponent implements OnInit, AfterViewInit { final Hero nullHero = null; Map product = {'name': 'frimfram', 'price': 42}; FormElement form; - String clickity = ''; + String clicked = ''; String clickMessage = ''; String clickMessage2 = ''; final String iconUrl = 'assets/images/ng-logo.png'; @@ -87,14 +90,14 @@ class AppComponent implements OnInit, AfterViewInit { int getVal() => val; - void onCancel(MouseEvent event) { - DivElement el = event.target; + void onCancel(UIEvent event) { + HtmlElement el = event?.target; var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : ''; alerter('Canceled. $evtMsg'); } - void onClickMe(MouseEvent event) { - DivElement el = event.target; + void onClickMe(UIEvent event) { + HtmlElement el = event?.target; var evtMsg = event != null ? 'Event target class is ${el.className}.' : ''; alerter('Click me. $evtMsg'); } @@ -103,9 +106,10 @@ class AppComponent implements OnInit, AfterViewInit { alerter('Deleted hero: ${hero?.firstName}'); } - bool onSave([MouseEvent event = null]) { + bool onSave([UIEvent event = null]) { + HtmlElement el = event?.target; var evtMsg = - event != null ? ' Event target is ${event.target.innerHtml}.' : ''; + event != null ? ' Event target is ${el.innerHtml}.' : ''; alerter('Saved. $evtMsg'); return false; } diff --git a/public/docs/_examples/template-syntax/dart/lib/app_component.html b/public/docs/_examples/template-syntax/dart/lib/app_component.html index 0400832633..c7542c3039 100644 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.html +++ b/public/docs/_examples/template-syntax/dart/lib/app_component.html @@ -31,11 +31,11 @@
* prefix and <template>
-Template local variables
+Template reference variables
Inputs and outputs
Pipes
Safe navigation operator ?.
- +Enums

Interpolation

@@ -105,9 +105,9 @@ -
click me
+
click me
-{{clickity}} +{{clicked}}

@@ -184,15 +184,14 @@ button - + - - - +
+ + + +
@@ -202,7 +201,7 @@ Interpolated:
Property bound:
The interpolated title is {{title}}
-
+
top @@ -258,9 +257,7 @@ Property bound:
Bad curly
-

Note: "Bad curly" should be smaller but isn't, due to - issue #6901.

+ [className]="badCurly">Bad curly
@@ -374,15 +371,15 @@ bindon-ngModel
+ [ngModel]="currentHero.firstName" + (ngModelChange)="currentHero.firstName=$event"> (ngModelChange) = "...firstName=$event"
+ [ngModel]="currentHero.firstName" + (ngModelChange)="setUpperCaseFirstName($event)"> (ngModelChange) = "setUpperCaseFirstName($event)"
@@ -443,7 +440,7 @@ bindon-ngModel -
Hello, {{nullHero.firstName}}
@@ -487,33 +484,33 @@ bindon-ngModel
-
Pick a toe
-
- You picked ... - - +
Pick a toe
+
+ You picked ... + + - - - Eenie - Meanie - Miney - Moe - other - + + + Eenie + Meanie + Miney + Moe + other + - - - - - - + + + + + + - - -
+
+ +
top @@ -620,7 +617,7 @@ bindon-ngModel

expand to <template>

@@ -644,15 +641,15 @@ bindon-ngModel top - -

Template local variables

+ +

Template reference variables

@@ -672,7 +669,7 @@ bindon-ngModel
+ [(ngModel)]="currentHero.firstName">
@@ -682,7 +679,7 @@ bindon-ngModel

- + top @@ -708,13 +705,15 @@ bindon-ngModel

Pipes

- -
{{ title | uppercase }}
+
Title through uppercase pipe: {{title | uppercase}}
- -
{{ title | uppercase | lowercase }}
+ +
+ Title through a pipe chain: + {{title | uppercase | lowercase}} +
@@ -723,16 +722,14 @@ bindon-ngModel - - +
{{currentHero}}
Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}
- {{product['price'] | currency:'$'}} + {{product['price'] | currency:'USD':false}}
top @@ -742,7 +739,7 @@ bindon-ngModel
- The title is {{ title }} + The title is {{title}}
@@ -759,11 +756,10 @@ bindon-ngModel - @@ -784,19 +780,16 @@ The null hero's name is {{nullHero.firstName}} top - + -

Enums in binding

- -

The current color number is {{color}}

-

- -top - - -

My First Angular Application

- +

+ + The name of the Color.red enum is {{colorRed}}.
+ The current color is {{color}} and its index is {{color.index}}.
+ + +

top diff --git a/public/docs/_examples/template-syntax/ts/app/app.component.html b/public/docs/_examples/template-syntax/ts/app/app.component.html index 37d5614cb2..ed43a2ff33 100644 --- a/public/docs/_examples/template-syntax/ts/app/app.component.html +++ b/public/docs/_examples/template-syntax/ts/app/app.component.html @@ -52,13 +52,13 @@ - -

The sum of 1 + 1 is {{1 + 1}}

+ +

The sum of 1 + 1 is {{1 + 1}}

- -

The sum of 1 + 1 is not {{1 + 1 + getVal()}}

+ +

The sum of 1 + 1 is not {{1 + 1 + getVal()}}

top @@ -66,8 +66,8 @@

New Mental Model

- - + +
Mental Model
@@ -184,13 +184,14 @@ button - - + +
+ + + +
@@ -199,8 +200,8 @@ button Interpolated:
Property bound: -
The interpolated title is {{title}}
-
+
The interpolated title is {{title}}
+
top @@ -278,13 +279,13 @@ Property bound:

Style Binding

- - + + - - + + top @@ -393,7 +394,7 @@ bindon-ngModel
This div is saveable and special
-After setClasses(), the classes are "{{classDiv.className}}" + After setClasses(), the classes are "{{classDiv.className}}"
@@ -409,8 +410,8 @@ After setClasses(), the classes are "{{classDiv.className}}"

NgStyle Binding

-
- This div is x-large +
+ This div is x-large.
@@ -418,12 +419,12 @@ After setClasses(), the classes are "{{classDiv.className}}"

setStyles returns {{setStyles() | json}}

- This div is italic, normal weight, and extra large (24px) + This div is italic, normal weight, and extra large (24px).

After setStyles(), the DOM confirms that the styles are - "{{getStyles(styleDiv)}}" + {{getStyles(styleDiv)}} .

@@ -439,7 +440,7 @@ After setClasses(), the classes are "{{classDiv.className}}" -
Hello, {{nullHero.firstName}}
@@ -603,22 +604,22 @@ After setClasses(), the classes are "{{classDiv.className}}"

* prefix and <template>

*ngIf expansion

-

*ngIf

- - - +

*ngIf

+ + + -

expand to template = "..."

- - - +

expand to template = "..."

+ + + -

expand to <template>

- - - +

expand to <template>

+ + +

*ngFor expansion

*ngFor

@@ -658,7 +659,7 @@ After setClasses(), the classes are "{{classDiv.className}}" - +

Example Form

@@ -704,13 +705,15 @@ After setClasses(), the classes are "{{classDiv.className}}"

Pipes

- -
{{ title | uppercase }}
+
Title through uppercase pipe: {{title | uppercase}}
- -
{{ title | uppercase | lowercase }}
+ +
+ Title through a pipe chain: + {{title | uppercase | lowercase}} +
@@ -720,16 +723,8 @@ After setClasses(), the classes are "{{classDiv.className}}"
{{currentHero | json}}
- - -
Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}
@@ -743,29 +738,29 @@ After setClasses(), the classes are "{{classDiv.className}}"

Safe navigation operator ?.

- -The title is {{ title }} - + + The title is {{title}} +
- -The current hero's name is {{currentHero?.firstName}} - + + The current hero's name is {{currentHero?.firstName}} +
- -The current hero's name is {{currentHero.firstName}} - + + The current hero's name is {{currentHero.firstName}} +
@@ -780,27 +775,25 @@ The null hero's name is {{nullHero && nullHero.firstName}}
- - -The null hero's name is {{nullHero?.firstName}} - + + + The null hero's name is {{nullHero?.firstName}} +
top - +

Enums in binding

-

The name of the Color.Red enum is {{Color[Color.Red]}}

-

The current color number is {{color}}

-

- -top - - -

My First Angular Application

- +

+ + The name of the Color.Red enum is {{Color[Color.Red]}}.
+ The current color is {{Color[color]}} and its number is {{color}}.
+ + +

top diff --git a/public/docs/_examples/template-syntax/ts/app/app.component.ts b/public/docs/_examples/template-syntax/ts/app/app.component.ts index 1333f9c24d..33ddaa9bf1 100644 --- a/public/docs/_examples/template-syntax/ts/app/app.component.ts +++ b/public/docs/_examples/template-syntax/ts/app/app.component.ts @@ -77,6 +77,9 @@ export class AppComponent implements AfterViewInit, OnInit { heroImageUrl = 'images/hero.png'; //iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png'; + clicked = ''; + clickMessage = ''; + clickMessage2 = ''; iconUrl = 'images/ng-logo.png'; isActive = false; isSpecial = true; diff --git a/public/docs/dart/latest/_util-fns.jade b/public/docs/dart/latest/_util-fns.jade index dedea10893..432da3b7fd 100644 --- a/public/docs/dart/latest/_util-fns.jade +++ b/public/docs/dart/latest/_util-fns.jade @@ -3,6 +3,7 @@ include ../../../_includes/_util-fns //- See the _util-fns file included above for a description of the use of these variables. - var _docsFor = 'dart'; - var _decorator = 'annotation'; +- var _Array = 'List'; - var _array = 'list'; - var _an_array = 'a list'; //- Deprecate now that we have the articles - var _a = 'an'; @@ -12,6 +13,8 @@ include ../../../_includes/_util-fns - var _Promise = 'Future'; - var _Observable = 'Stream'; - var _liveLink = 'sample repo'; +- var _truthy = 'true'; +- var _falsey = 'false'; mixin liveExampleLink(linkText, exampleUrlPartName) - var text = linkText || 'live example'; diff --git a/public/docs/dart/latest/guide/template-syntax.jade b/public/docs/dart/latest/guide/template-syntax.jade index 893e53e825..8ba4989112 100644 --- a/public/docs/dart/latest/guide/template-syntax.jade +++ b/public/docs/dart/latest/guide/template-syntax.jade @@ -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 = ';'; + - var __new_op = 'new or const'; + - var mapApiRef = 'https://api.dartlang.org/stable/1.16.0/dart-core/Map-class.html'; + - var __objectAsMap = 'Map' -:marked - 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 +block notable-differences :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). + * 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-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 (`;`). - - 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') - -
-table - tr - th Binding type - th Target - th Examples - tr - td Property - td. - Element property
- Component property
- Directive property - td - +makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-syntax-1')(format=".") - tr - td Event - td. - Element event
- Component event
- 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. - class property - td - +makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-syntax-1')(format=".") - tr - td Style - td. - style property - td - +makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-syntax-1')(format=".") -
- -+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 +block template-expressions-cannot :marked - In checked mode, uncommenting the `` element above causes a type exception, - because `String` isn't a subtype of `Hero`. - For information on checked mode, see [Important concepts](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#important-concepts) - in the Dart language tour. -+includeShared('{ts}', 'property-binding-12') -+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') + Perhaps more surprising, template expressions can’t refer to static + properties, nor to top-level variables or functions, such as `window` or + `document` from `dart:html`. They can’t directly call `print` or functions + imported from `dart:math`. They are restricted to referencing members of + the expression context. -+includeShared('{ts}', 'other-bindings-1') -+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') - -.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 +block statement-context :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"`. + Template statements can’t refer to static properties on the class, nor to + top-level variables or functions, such as `window` or `document` from + `dart:html`. They can’t directly call `print` or functions imported from + `dart:math`. - 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). -+includeShared('{ts}', 'directives-ngIf-4') -+makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-3')(format=".") -+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') +block dart-type-exceptions + .callout.is-helpful + header Dart difference: Type exceptions + :marked + In checked mode, if the template expression result type and the target + property type are not assignment compatible, then a type exception will + be thrown. + For information on checked mode, see [Important concepts](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#important-concepts) + in the Dart language tour. -+includeShared('{ts}', 'star-template') -+includeShared('{ts}', 'star-template-ngIf-1') -+makeExample('template-syntax/dart/lib/app_component.html', 'Template-1')(format=".") -+includeShared('{ts}', 'star-template-ngIf-2a') -+makeExample('template-syntax/dart/lib/app_component.html', 'Template-2a')(format=".") -+includeShared('{ts}', 'star-template-ngIf-2') -+makeExample('template-syntax/dart/lib/app_component.html', 'Template-2')(format=".") -+includeShared('{ts}', '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! +block dart-type-exception-example + .callout.is-helpful + header Dart difference: Type exception example + :marked + In checked mode, the code above will result in a type exception: + `String` isn't a subtype of `Hero`. + +block dart-class-binding-bug + .callout.is-helpful + header Angular Issue #6901 + :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 - 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. -+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') + Dart throws an exception, and so does Angular: + code-example(format="nocode"). + EXCEPTION: The null object does not have a getter 'firstName'. -+includeShared('{ts}', 'ref-vars') -+makeExample('template-syntax/dart/lib/app_component.html', 'ref-phone')(format=".") -+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=".") -
- :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=".") - - -.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') +block safe-op-alt + //- N/A diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade index 8933106cb7..9f1e008a79 100644 --- a/public/docs/ts/latest/guide/template-syntax.jade +++ b/public/docs/ts/latest/guide/template-syntax.jade @@ -1,8 +1,13 @@ -include ../_util-fns +block includes + include ../_util-fns + - var _JavaScript = 'JavaScript'; + //- Double underscore means don't escape var, use !{__var}. + - var __chaining_op = '; or ,'; + - var __new_op = 'new'; + - var __objectAsMap = 'object'; -// #docregion intro :marked - Our Angular application manages what the user sees and does through the interaction of a Component class instance (the *component*) and its user-facing template. + Our Angular application manages what the user sees and can do, achieving this through the interaction of a Component class instance (the *component*) and its user-facing template. Many of us are familiar with the component/template duality from our experience with model-view-controller (MVC) or model-view-viewmodel (MVVM). In Angular, the component plays the part of the controller/viewmodel, and the template represents the view. @@ -28,22 +33,20 @@ include ../_util-fns * [Input and output properties](#inputs-outputs) * [Template expression operators](#expression-operators) * [pipe](#pipe) - * ["safe navigation operator" (?.)](#safe-navigation-operator) -// #enddocregion intro -.l-sub-section - :marked - The [live example](/resources/live-examples/template-syntax/ts/plnkr.html) - demonstrates all of the syntax and code snippets described in this chapter. + * [safe navigation operator (?.)](#safe-navigation-operator) + +p. + The #[+liveExampleLink2()] + demonstrates all of the syntax and code snippets described in this chapter. -// #docregion html-1 .l-main-section :marked ## HTML HTML is the language of the Angular template. Our [QuickStart](../quickstart.html) application had a template that was pure HTML: -// #enddocregion html-1 -+makeExample('template-syntax/ts/app/app.component.html', 'my-first-app')(format=".") -// #docregion html-2 +code-example(language="html" escape="html"). +

My First Angular 2 App

+ :marked Almost all HTML syntax is valid template syntax. The `