diff --git a/.gitignore b/.gitignore index 876c599690..16793c2110 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ plnkr.html *plnkr.no-link.html public/docs/*/latest/guide/cheatsheet.json protractor-results.txt + +public/docs/ts/latest/guide/_.*.jade diff --git a/public/docs/_examples/template-syntax/dart/.analysis_options b/public/docs/_examples/template-syntax/dart/.analysis_options new file mode 100644 index 0000000000..4fcc97bfe6 --- /dev/null +++ b/public/docs/_examples/template-syntax/dart/.analysis_options @@ -0,0 +1,3 @@ +linter: + rules: + - always_declare_return_types 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 7d24be4155..b83acd4f42 100644 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.dart +++ b/public/docs/_examples/template-syntax/dart/lib/app_component.dart @@ -1,15 +1,14 @@ // #docregion -library template_syntax.app_component; - -import 'dart:html'; import 'dart:convert'; +import 'dart:html'; import 'package:angular2/angular2.dart'; -import 'package:template_syntax/hero.dart'; -import 'package:template_syntax/hero_detail_component.dart'; -import 'package:template_syntax/my_click_directive.dart'; -enum _Color { Red, Green, Blue } +import 'hero.dart'; +import 'hero_detail_component.dart'; +import 'my_click_directive.dart'; + +enum Color { Red, Green, Blue } @Component( selector: 'my-app', @@ -24,37 +23,54 @@ class AppComponent { String heroName; String help; String actionName = 'Go for it'; +// String badCurly = 'special'; // XXX: This isn't working. +// String badCurly = 'bad, curly'; // XXX: This isn't working. +// String badCurly = 'bad curly'; // XXX: This isn't working. + String badCurly = 'bad'; // XXX: This isn't working. +// List badCurly = ['bad', 'curly']; // XXX: This isn't working. String title = 'Template Syntax'; - String heroImageUrl = 'assets/images/hero.png'; - String villainImageUrl = 'assets/images/villain.png'; - String iconUrl = 'assets/images/ng-logo.png'; - String chosenToe; + String toeChoice; int val = 2; bool canSave = true; bool isActive = false; bool isSpecial = true; bool isUnchanged = true; bool isSelected = false; - _Color color = _Color.Red; + Color color = Color.Red; List heroes = Hero.MockHeroes; Hero selectedHero = Hero.MockHeroes[0]; Hero currentHero = Hero.MockHeroes[0]; - Hero nullHero = null; + final Hero nullHero = null; Map product = {'name': 'frimfram', 'price': 42}; - Event clickity; FormElement form; + String clickity = ''; + String clickMessage = ''; + String clickMessage2 = ''; + final String iconUrl = 'assets/images/ng-logo.png'; + // heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png'; + // Public Domain terms of use: http://www.wpclipart.com/terms.html + final String heroImageUrl = 'assets/images/hero.png'; + + // villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png' + // Public Domain terms of use http://www.clker.com/disclaimer.html + final String villainImageUrl = 'assets/images/villain.png'; + + // #docregion setClasses Map classes = { - 'saveable': false, // true - 'modified': false, // false - 'special': false // true + 'saveable': false, + 'modified': false, + 'special': false }; + // #enddocregion setClasses + // #docregion setStyles Map styles = { 'font-style': 'normal', 'font-weight': 'normal', 'font-size': 'smaller' }; + // #enddocregion setStyles Map styles2 = { 'fontStyle': 'normal', @@ -66,31 +82,31 @@ class AppComponent { void callFax(String value) => alerter('Faxing $value ...'); void callPhone(String value) => alerter('Calling $value ...'); void colorToggle() { - color = color == _Color.Red ? _Color.Blue : _Color.Red; + color = (color == Color.Red) ? Color.Blue : Color.Red; } - int get getVal => val; + int getVal() => val; void onCancel(MouseEvent event) { DivElement el = event.target; - var evtMsg = event != null ? 'Event target is ${el.innerHtml}' : ''; + var evtMsg = event != null ? 'Event target is ${el.innerHtml}.' : ''; alerter('Canceled. $evtMsg'); } void onClickMe(MouseEvent event) { DivElement el = event.target; - var evtMsg = event != null ? 'Event target class is ${el.className}' : ''; + var evtMsg = event != null ? 'Event target class is ${el.className}.' : ''; alerter('Click me. $evtMsg'); } bool onSave([MouseEvent event = null]) { var evtMsg = - event != null ? ' Event target is ${event.target.innerHtml}' : ''; - alerter('Saved.$evtMsg'); + event != null ? ' Event target is ${event.target.innerHtml}.' : ''; + alerter('Saved. $evtMsg'); return false; } - void onHeroDeleted(Hero hero) => alerter('Deleted hero: ${hero.firstName}'); + void onHeroDeleted([Hero hero]) => alerter('Deleted hero: ${hero?.firstName}'); void onSubmit(NgForm form) { var evtMsg = form.valid @@ -108,40 +124,32 @@ class AppComponent { return JSON.encode(showStyles); } - // #docregion setStyles - Map setStyles() { - styles['font-style'] = canSave ? 'italic' : 'normal'; - styles['font-weight'] = !isUnchanged ? 'bold' : 'normal'; - styles['font-size'] = isSpecial ? 'x-large' : 'smaller'; - return styles; - } - // #enddocregion setStyles - - // #docregion setStyles2 - Map setStyles2() { - // camelCase style properties work too [PENDING: no, they don't] - styles2['fontStyle'] = canSave ? 'italic' : 'normal'; - styles2['fontWeight'] = !isUnchanged ? 'bold' : 'normal'; - styles2['fontSize'] = isSpecial ? 'x-large' : 'smaller'; - return styles2; - } - // #enddocregion setStyles2 - + // #docregion setClasses Map setClasses() { - classes['saveable'] = canSave; - classes['modified'] = !isUnchanged; - classes['special'] = isSpecial; + classes['saveable'] = canSave; // true + classes['modified'] = !isUnchanged; // false + classes['special'] = isSpecial; // true return classes; } + // #enddocregion setClasses + + // #docregion setStyles + Map setStyles() { + styles['font-style'] = canSave ? 'italic' : 'normal'; // italic + styles['font-weight'] = !isUnchanged ? 'bold' : 'normal'; // normal + styles['font-size'] = isSpecial ? '24px' : '8px'; // 24px + return styles; + } + // #enddocregion setStyles String toeChooser(Element picker) { List choices = picker.children; for (var i = 0; i < choices.length; i++) { var choice = choices[i]; if (choice.checked) { - chosenToe = choice.value; - return chosenToe; + toeChoice = choice.value; + return toeChoice; } } } 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 5139df32c9..c1995edada 100644 --- a/public/docs/_examples/template-syntax/dart/lib/app_component.html +++ b/public/docs/_examples/template-syntax/dart/lib/app_component.html @@ -23,7 +23,7 @@ -

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

+

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

@@ -69,9 +69,9 @@ -
click me
+
click me
- +{{clickity}}

@@ -146,15 +146,17 @@ button - + + - +
The title is {{title}}
-
+
@@ -208,9 +210,10 @@ button - +
Bad curly
+ [class]="badCurly">Bad curly
@@ -257,10 +260,10 @@ button -
click with myClick
+
click with myClick
-{{clickity}} +{{clickMessage}} @@ -362,32 +365,22 @@ bindon-ngModel
- This div is x-large + This div is x-large.

Use setStyles() - CSS property names

-

setStyles returns {{setStyles() | json}}

+

setStyles returns {{setStyles()}}.

- This div is italic, normal weight, and x-large + This div is italic, normal weight, and extra large (24px).
-
- After setStyles(), the styles are "{{getStyles(styleDiv)}}" -
- - -

Use setStyles2() - camelCase style property names

-

setStyles2 returns {{setStyles2() | json}}

- -
- This div is italic, normal weight, and x-large -
- -
- After setStyles2(), the styles are "{{getStyles(styleDiv2)}}" -
+

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

@@ -401,7 +394,7 @@ bindon-ngModel -
Hello, {{nullHero.firstName}}
@@ -446,17 +439,17 @@ bindon-ngModel
-
Pick a toe
-
You picked - - - - - - - - - +
Pick a toe
+
You picked + + + + + + + + +
@@ -480,8 +473,8 @@ bindon-ngModel
- +
{{i + 1}} - {{hero.fullName}}
@@ -567,10 +560,8 @@ bindon-ngModel - +
myClick2
+{{clickMessage2}}

Pipes

@@ -591,14 +582,10 @@ PENDING: I don't see clicked2 defined anywhere in the TS example - + + - @@ -606,7 +593,7 @@ PENDING: I don't see clicked2 defined anywhere in the TS example
- + {{product['price'] | currency:'$'}}
@@ -632,11 +619,12 @@ PENDING: I don't see clicked2 defined anywhere in the TS example
+ @@ -644,11 +632,7 @@ See console log
The null hero's name is {{nullHero.firstName}}
-
- - The null hero's name is {{nullHero != null && nullHero.firstName != null}} - -
+
@@ -660,8 +644,9 @@ See console log +

The current color number is {{color}}

-

+

+--> diff --git a/public/docs/_examples/template-syntax/dart/lib/hero.dart b/public/docs/_examples/template-syntax/dart/lib/hero.dart index 730cac5f7a..23adafb866 100644 --- a/public/docs/_examples/template-syntax/dart/lib/hero.dart +++ b/public/docs/_examples/template-syntax/dart/lib/hero.dart @@ -1,6 +1,4 @@ // #docregion -library template_syntax.hero; - class Hero { static int _nextId = 1; @@ -18,7 +16,7 @@ class Hero { static List MockHeroes = [ new Hero('Hercules', lastName: 'Son of Zeus', - birthdate: new DateTime(1970, 1, 25), + birthdate: new DateTime(1970, 2, 25), url: 'http://www.imdb.com/title/tt0065832/', rate: 325), new Hero('eenie', lastName: 'toe'), @@ -27,5 +25,10 @@ class Hero { new Hero('Moe', lastName: 'Toe') ]; - String get fullName => '$firstName $lastName'; + String get fullName { + if (lastName == null) return firstName; + return '$firstName $lastName'; + } + + String toString() => '$fullName (rate: $rate)'; } diff --git a/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart b/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart index 11af1be00b..fe82d76fe1 100644 --- a/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart +++ b/public/docs/_examples/template-syntax/dart/lib/hero_detail_component.dart @@ -1,8 +1,8 @@ +// #docplaster // #docregion -library template_syntax.hero_detail_component; - import 'package:angular2/angular2.dart'; -import 'package:template_syntax/hero.dart'; + +import 'hero.dart'; var nextHeroDetailId = 1; @@ -11,28 +11,40 @@ var nextHeroDetailId = 1; // #enddocregion input-output-2 selector: 'hero-detail', // #docregion input-output-2 + // ... inputs: const ['hero'], outputs: const ['deleted'], // #enddocregion input-output-2 - template: '''

- {{hero?.fullName}} + template: ''' +
+ {{hero?.fullName}} - delete -
''' + delete +
+''' // #docregion input-output-2 ) // #enddocregion input-output-2 class HeroDetailComponent { - Hero hero; - // #docregion deleted - + Hero hero = new Hero('Zzzzzzzz'); // default sleeping hero String heroImageUrl = 'assets/images/hero.png'; - final EventEmitter deleted = new EventEmitter(); + String lineThrough = ''; // PENDING: use null instead? - onDelete() { - deleted.add(hero); + // #docregion deleted + final EventEmitter deleted = new EventEmitter(); + // #enddocregion deleted + + HeroDetailComponent() { + deleted.listen((Hero _) { + lineThrough = (lineThrough == '') ? 'line-through' : ''; + }); } -// #enddocregion deleted + + // #docregion deleted + onDelete() { + deleted.emit(hero); + } + // #enddocregion deleted } @Component( @@ -41,7 +53,8 @@ class HeroDetailComponent { inputs: ['hero'], outputs: ['deleted'], */ - template: '''
+ template: ''' +
{{hero?.fullName}}
First: {{hero?.firstName}}
@@ -51,17 +64,17 @@ class HeroDetailComponent {
Rate/hr: {{hero?.rate | currency:'EUR'}}

-
''') +
+''') class BigHeroDetailComponent extends HeroDetailComponent { // #docregion input-output-1 @Input() Hero hero; - @Output() - final EventEmitter deleted = new EventEmitter(); + @Output() final EventEmitter deleted = new EventEmitter(); // #enddocregion input-output-1 String heroImageUrl = 'assets/images/hero.png'; onDelete() { - deleted.add(hero); + deleted.emit(hero); } } diff --git a/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart b/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart index c0aaa77e4b..74299c19c1 100644 --- a/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart +++ b/public/docs/_examples/template-syntax/dart/lib/my_click_directive.dart @@ -1,6 +1,4 @@ -// #docregion -library template_syntax.my_click_directive; - +// #docplaster import 'dart:html'; import 'package:angular2/angular2.dart'; @@ -8,12 +6,18 @@ import 'package:angular2/angular2.dart'; @Directive(selector: '[myClick]') class MyClickDirective { // #docregion my-click-output-1 - @Output() - final EventEmitter clicks = new EventEmitter(); + // @Output(alias) [type info] propertyName = ... + @Output('myClick') final EventEmitter clicks = new EventEmitter(); + // #enddocregion my-click-output-1 + bool _toggle = false; MyClickDirective(ElementRef el) { - el.nativeElement.onClick.listen(this.clicks.add('Click!')); + Element nativeEl = el.nativeElement; + nativeEl.onClick.listen((Event e) { + _toggle = !_toggle; + clicks.emit(_toggle ? 'Click!' : ''); + }); } } @@ -22,12 +26,17 @@ class MyClickDirective { // #enddocregion my-click-output-2 selector: '[myClick2]', // #docregion my-click-output-2 - outputs: const ['clicks:myClick']) + // ... + outputs: const ['clicks:myClick']) // propertyName:alias // #enddocregion my-click-output-2 class MyClickDirective2 { final EventEmitter clicks = new EventEmitter(); + bool _toggle = false; - MyClickDirective(ElementRef el) { - el.nativeElement.onClick.listen(this.clicks.add('Click!')); + MyClickDirective2(ElementRef el) { + el.nativeElement.onClick.listen((Event e) { + _toggle = !_toggle; + clicks.emit(_toggle ? 'Click2!' : ''); + }); } } diff --git a/public/docs/_examples/template-syntax/dart/pubspec.yaml b/public/docs/_examples/template-syntax/dart/pubspec.yaml index 5eca0898e5..55397cac9b 100644 --- a/public/docs/_examples/template-syntax/dart/pubspec.yaml +++ b/public/docs/_examples/template-syntax/dart/pubspec.yaml @@ -1,12 +1,19 @@ +# #docregion name: template_syntax description: Template Syntax version: 0.0.1 +environment: + sdk: '>=1.13.0 <2.0.0' dependencies: - angular2: 2.0.0-beta.0 + angular2: 2.0.0-beta.3 browser: ^0.10.0 + dart_to_js_script_rewriter: ^0.1.0 transformers: - angular2: + platform_pipes: 'package:angular2/common.dart#COMMON_PIPES' platform_directives: - 'package:angular2/common.dart#COMMON_DIRECTIVES' - 'package:angular2/common.dart#FORM_DIRECTIVES' entry_points: web/main.dart +- dart_to_js_script_rewriter + diff --git a/public/docs/_examples/template-syntax/dart/web/index.html b/public/docs/_examples/template-syntax/dart/web/index.html index 70b49ac772..32d12818ef 100644 --- a/public/docs/_examples/template-syntax/dart/web/index.html +++ b/public/docs/_examples/template-syntax/dart/web/index.html @@ -3,11 +3,11 @@ Template Syntax - + Loading... - \ No newline at end of file + diff --git a/public/docs/_examples/template-syntax/dart/web/style.css b/public/docs/_examples/template-syntax/dart/web/styles.css similarity index 100% rename from public/docs/_examples/template-syntax/dart/web/style.css rename to public/docs/_examples/template-syntax/dart/web/styles.css diff --git a/public/docs/dart/latest/guide/template-syntax-NEW.jade b/public/docs/dart/latest/guide/template-syntax-NEW.jade new file mode 100644 index 0000000000..31d6281ce8 --- /dev/null +++ b/public/docs/dart/latest/guide/template-syntax-NEW.jade @@ -0,0 +1,397 @@ +include ../../../../_includes/_util-fns + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'intro') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'html-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'my-first-app')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'html-2') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'first-interpolation')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'title+image')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'sum-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-4') ++makeExample('template-syntax/dart/lib/app_component.html', 'sum-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'interpolation-5') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-expressions-1') +:marked + We write template expressions in a language that looks like Dart. + Many Dart expressions are legal template expressions, but not all. + Dart expressions that have or promote side effects are prohibited, + including: **[QUESTION: is this list correct? I removed mentions of chaining with , and ;.]** + + * assignments (`=`, `+=`, `-=`, ...) + * creating instances using `new` or `const` + * increment and decrement (`++` and `--`) + + Other notable differences from Dart syntax include: + **[QUESTION: I wasn't able to use Dart interpolation inside a String, + which I had just assumed would work. How should we talk about that? + What else isn't allowed?]** + + * no support for the bitwise operators `|` and `&` + * new [template expression operators](#expression-operators), such as `|` +.callout.is-helpful + header Dart difference: Template expression operators + :marked + [PENDING: say something about stuff you might find in a24ts template expressions + but not in dart template expressions, and vice versa.] ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-expressions-context') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-expressions-guidelines') +:marked + Dependent values should not change during a single turn of the event loop. + If an idempotent expression returns a string or a number, it returns the same string or number + when called twice in a row. If the expression returns an object (including a `DateTime`, `Map`, or `List`), + it returns the same object *reference* when called twice in a row. + +.callout.is-helpful + header Dart difference: Arrays are lists + :marked + Arrays in JavaScript correspond to lists in Dart + (instances of the `List` class). + This chapter uses _array_ and _list_ interchangeably. + For more information, see + [Lists](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#lists) + in the [Dart language tour](https://www.dartlang.org/docs/dart-up-and-running/ch02.html). + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-statements-1') +:marked + Like template expressions, template *statements* use a language that looks like Dart. + The template statement parser is different than the template expression parser and + specifically supports both basic assignment (`=`) and chaining expressions with semicolons (`;`) and commas (`,`). + **[QUESTION: is that true — would `,` really work? is "chaining" really the word we want to use?]** + + However, certain Dart syntax is not allowed: + * the `new` and `const` keywords **[QUESTION: I guessed about `const`. Is it true?]** + * increment and decrement operators, `++` and `--` + * operator assignment, such as `+=` and `-=` + * the bitwise operators `|` and `&` + * the [template expression operators](#expression-operators) + **[QUESTION: can you really not use `?.`?]** + +.callout.is-helpful + header Dart difference: Template statement operators + :marked + [PENDING: say something about stuff you might find in a24ts statements + but not in dart statements, and vice versa.] ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'template-statements-3') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'img+button')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'hero-detail-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'disabled-button-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-4') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-attribute-vs-property') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-5') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-world-without-attributes') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'binding-syntax-targets') + +
+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/latest/guide/template-syntax.jade', 'binding-syntax-end') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-4') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-5') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-6') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-7') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-8') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-5')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-9') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-10') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-4')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-11') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-6')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-12') ++makeExample('template-syntax/dart/lib/app_component.html', 'property-binding-vs-interpolation')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'property-binding-13') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-1') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-colspan')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'attrib-binding-aria')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-class-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-class-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-2')(format=".") +// + +includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-class-3') +:marked + Finally, we can bind to a specific class name. + Angular adds the class when the template expression evaluates to `true`. + It removes the class when the expression evaluates to `false`. ++makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-class-4') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-style-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-style-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'style-binding-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'other-bindings-style-3') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-4') ++makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-5') ++makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-6') ++makeExample('template-syntax/dart/lib/hero_detail_component.dart', 'deleted', 'lib/hero_detail_component.dart (excerpt)')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-7') ++makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-to-component')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'event-binding-8') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'without-NgModel')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-4') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-5') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-6') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgModel-4')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'ngModel-7') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'event-binding-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-2') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngClass-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'class-binding-3a')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngClass-2') ++makeExample('template-syntax/dart/lib/app_component.dart', 'setClasses')(format=".") +// PENDING: Add "Dart difference" for returning maps in Dart? for omitting unnecessary `this.`s? ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngClass-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgClass-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngStyle-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngStyle-2') ++makeExample('template-syntax/dart/lib/app_component.dart', 'setStyles')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngStyle-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgStyle-2')(format=".") +// + +includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngIf-1') + +.l-main-section +:marked + ### NgIf + We can add an element subtree (an element and its children) to the DOM by binding an `NgIf` directive to a `true` expression. ++makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngIf-2') +// + +includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngIf-3') +:marked + Binding to a false expression removes the element subtree from the DOM. ++makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-2')(format=".") +.callout.is-helpful + header Dart difference: No truthy values + :marked + In checked mode, Dart expects Boolean values + (those with type `bool`) to be either `true` or `false`. + Even in production mode, the only value Dart treats as `true` is + the value `true`; all other values are `false`. + TypeScript and JavaScript, on the other hand, treat + many values (including non-null objects) as true. + A TypeScript Angular 2 program, for example, often has code like + `*ngIf="currentHero"` where a Dart program has code like + `*ngIf="currentHero != null"`. + + When converting TypeScript code to Dart code, watch out for + true/false problems. For example, forgetting the `!= null` + can lead to error messages such as + "[TODO: Put error message here]". + For more information, see + [Booleans](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#booleans) + in the [Dart language tour](https://www.dartlang.org/docs/dart-up-and-running/ch02.html). ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngIf-4') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgIf-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngIf-5') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngSwitch-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgSwitch')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngSwitch-2') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-3') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-4') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-5') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-6') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'directives-ngFor-7') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngIf-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'Template-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngIf-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'Template-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngIf-3') +// Changed from RED to ORANGE, since this isn't so dire a situation in Dart. +.callout.is-important + header Remember the brackets! + :marked + Don’t make the mistake of writing `ngIf="currentHero"`! + That syntax assigns the *string* value "currentHero" to `ngIf`, + which won't work because `ngIf` expects a bool. **[QUESTION: Did I get that right?]** ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'NgFor-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'Template-3')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'Template-4')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'star-template-ngFor-4') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'Template-4')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-2') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-refs') ++makeExample('template-syntax/dart/lib/app_component.html', 'var-phone')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-value') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-form-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'var-form')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-form-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'var-form-a')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'local-vars-form-3') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'io-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'io-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-3') ++makeExample('template-syntax/dart/lib/hero_detail_component.dart', 'input-output-1')(format=".") +:marked +.l-sub-section + :marked + Alternatively, we can identify members in the `inputs` and `outputs` arrays + of the directive metadata, as in this example: + +makeExample('template-syntax/dart/lib/hero_detail_component.dart', 'input-output-2')(format=".") +
+ :marked + We can specify an input/output property either with a decorator or in a metadata array. + Don't do both! ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-4') ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-5') ++makeExample('template-syntax/dart/lib/app_component.html', 'my-click')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'inputs-outputs-6') ++makeExample('template-syntax/dart/lib/my_click_directive.dart', 'my-click-output-1')(format=".") +.l-sub-section + :marked + We can also alias property names in the `inputs` and `outputs` arrays. + We write a colon-delimited (`:`) string with + the directive property name on the *left* and the public alias on the *right*: + +makeExample('template-syntax/dart/lib/my_click_directive.dart', 'my-click-output-2')(format=".") + + +.l-main-section +:marked + ## Template expression operators + The template expression language employs a subset of Dart syntax supplemented with a few special operators + for specific scenarios. We'll cover two of these operators: _pipe_ and _Elvis_. +.callout.is-helpful + header Dart difference: ?. is a Dart operator + :marked + The Elvis operator (`?.`) is part of the Dart language. + It's considered a template expression operator because + Angular 2 supports `?.` even in TypeScript and JavaScript apps. ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-pipe-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'pipes-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-pipe-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'pipes-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-pipe-3') ++makeExample('template-syntax/dart/lib/app_component.html', 'pipes-3')(format=".") +// + NOTE: Intentionally omit discussion of the json pipe. + +includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-pipe-4') + +makeExample('template-syntax/dart/lib/app_component.html', 'pipes-json')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-1') ++makeExample('template-syntax/dart/lib/app_component.html', 'elvis-2')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-2') ++makeExample('template-syntax/dart/lib/app_component.html', 'elvis-1')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-3') +// +includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-4') +:marked + Dart throws an exception, and so does Angular: +code-example(format="" language="html"). + EXCEPTION: The null object does not have a getter 'firstName'. ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-5') ++makeExample('template-syntax/dart/lib/app_component.html', 'elvis-4')(format=".") + +// + NOTE: Intentionally skip ugly null checking you wouldn't do in Dart. + +includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-6') + +makeExample('template-syntax/dart/lib/app_component.html', 'elvis-5')(format=".") + +includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-7') +:marked + This approach has merit but can be cumbersome, especially if the property path is long. + Imagine guarding against a null somewhere in a long property path such as `a.b.c.d`. ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-8') ++makeExample('template-syntax/dart/lib/app_component.html', 'elvis-6')(format=".") ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'expression-operators-elvis-9') + ++includeShared('../../../ts/latest/guide/template-syntax.jade', 'summary') diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade index a4da8ba5a6..e3197e325c 100644 --- a/public/docs/ts/latest/guide/template-syntax.jade +++ b/public/docs/ts/latest/guide/template-syntax.jade @@ -1,5 +1,6 @@ include ../../../../_includes/_util-fns +// #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. @@ -21,33 +22,44 @@ include ../../../../_includes/_util-fns * [Local template variables](#local-vars) * [Input and output properties](#inputs-outputs) * [Template expression operators](#expression-operators) +// #enddocregion intro +:marked [Run the live example](/resources/live-examples/template-syntax/ts/plnkr.html) +// #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: + 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 :marked - Almost all HTML syntax is valid template syntax. The `