From a48b307aed25042819549efe27828f1e2e43b520 Mon Sep 17 00:00:00 2001 From: Luis Vargas Date: Wed, 16 Mar 2016 14:39:06 -0400 Subject: [PATCH] docs(toh/dart): add toh-5 sample files and link to them closes #971 --- .../toh-5/dart/lib/app_component.css | 31 + .../toh-5/dart/lib/app_component.dart | 46 ++ .../toh-5/dart/lib/app_component_1.dart | 26 + .../toh-5/dart/lib/app_component_2.dart | 32 + .../toh-5/dart/lib/dashboard_component.css | 63 ++ .../toh-5/dart/lib/dashboard_component.dart | 43 ++ .../toh-5/dart/lib/dashboard_component.html | 11 + .../toh-5/dart/lib/dashboard_component_1.dart | 8 + .../toh-5/dart/lib/dashboard_component_2.dart | 25 + .../docs/_examples/toh-5/dart/lib/hero.dart | 6 + .../toh-5/dart/lib/hero_detail_component.css | 30 + .../toh-5/dart/lib/hero_detail_component.dart | 56 ++ .../toh-5/dart/lib/hero_detail_component.html | 14 + .../toh-5/dart/lib/hero_service.dart | 27 + .../toh-5/dart/lib/heroes_component.css | 59 ++ .../toh-5/dart/lib/heroes_component.dart | 51 ++ .../toh-5/dart/lib/heroes_component.html | 21 + .../_examples/toh-5/dart/lib/mock_heroes.dart | 14 + public/docs/_examples/toh-5/dart/pubspec.yaml | 18 + .../docs/_examples/toh-5/dart/web/index.html | 24 + .../docs/_examples/toh-5/dart/web/main.dart | 7 + public/docs/dart/latest/tutorial/index.jade | 14 +- public/docs/dart/latest/tutorial/toh-pt1.jade | 15 +- public/docs/dart/latest/tutorial/toh-pt2.jade | 15 +- public/docs/dart/latest/tutorial/toh-pt3.jade | 15 +- public/docs/dart/latest/tutorial/toh-pt4.jade | 15 +- .../dart/latest/tutorial/toh-pt5-NEW.jade | 699 ++++++++++++++++++ public/docs/dart/latest/tutorial/toh-pt5.jade | 15 +- 28 files changed, 1394 insertions(+), 6 deletions(-) create mode 100644 public/docs/_examples/toh-5/dart/lib/app_component.css create mode 100644 public/docs/_examples/toh-5/dart/lib/app_component.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/app_component_1.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/app_component_2.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component.css create mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component.html create mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/hero.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/hero_detail_component.css create mode 100644 public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/hero_detail_component.html create mode 100644 public/docs/_examples/toh-5/dart/lib/hero_service.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/heroes_component.css create mode 100644 public/docs/_examples/toh-5/dart/lib/heroes_component.dart create mode 100644 public/docs/_examples/toh-5/dart/lib/heroes_component.html create mode 100644 public/docs/_examples/toh-5/dart/lib/mock_heroes.dart create mode 100644 public/docs/_examples/toh-5/dart/pubspec.yaml create mode 100644 public/docs/_examples/toh-5/dart/web/index.html create mode 100644 public/docs/_examples/toh-5/dart/web/main.dart create mode 100644 public/docs/dart/latest/tutorial/toh-pt5-NEW.jade diff --git a/public/docs/_examples/toh-5/dart/lib/app_component.css b/public/docs/_examples/toh-5/dart/lib/app_component.css new file mode 100644 index 0000000000..137e9be7be --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/app_component.css @@ -0,0 +1,31 @@ +/* #docplaster */ +/* #docregion css */ +h1 { + font-size: 1.2em; + color: #999; + margin-bottom: 0; +} +h2 { + font-size: 2em; + margin-top: 0; + padding-top: 0; +} +nav a { + padding: 5px 10px; + text-decoration: none; + margin-top: 10px; + display: inline-block; + background-color: #eee; + border-radius: 4px; +} +nav a:visited, a:link { + color: #607D8B; +} +nav a:hover { + color: #039be5; + background-color: #CFD8DC; +} +nav a.router-link-active { + color: #039be5; +} +/* #enddocregion css */ diff --git a/public/docs/_examples/toh-5/dart/lib/app_component.dart b/public/docs/_examples/toh-5/dart/lib/app_component.dart new file mode 100644 index 0000000000..9af70e7ebe --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/app_component.dart @@ -0,0 +1,46 @@ +// #docplaster +// #docregion +import 'package:angular2/angular2.dart'; +import 'package:angular2/router.dart'; + +import 'package:angular2_tour_of_heroes/heroes_component.dart'; +import 'package:angular2_tour_of_heroes/hero_service.dart'; +import 'package:angular2_tour_of_heroes/dashboard_component.dart'; +// #docregion hero-detail-import +import 'package:angular2_tour_of_heroes/hero_detail_component.dart'; +// #enddocregion hero-detail-import + +@Component( + selector: 'my-app', + // #docregion template + template: ''' +

{{title}}

+ + ''', + // #enddocregion template + // #docregion style-urls + styleUrls: const ['app_component.css'], + // #enddocregion style-urls + directives: const [ROUTER_DIRECTIVES], + providers: const [HeroService, ROUTER_PROVIDERS]) +@RouteConfig(const [ +// #docregion dashboard-route + const Route( + path: '/dashboard', + name: 'Dashboard', + component: DashboardComponent, + useAsDefault: true), +// #enddocregion dashboard-route +// #docregion hero-detail-route + const Route( + path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent), +// #enddocregion hero-detail-route + const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent) +]) +class AppComponent { + String title = 'Tour of Heroes'; +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/app_component_1.dart b/public/docs/_examples/toh-5/dart/lib/app_component_1.dart new file mode 100644 index 0000000000..3a109d2321 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/app_component_1.dart @@ -0,0 +1,26 @@ +// #docplaster +// #docregion +import 'package:angular2/angular2.dart'; +// #enddocregion +import 'package:angular2/router.dart'; // for testing only +// #docregion + +import 'hero_service.dart'; +import 'heroes_component.dart'; + +@Component( + selector: 'my-app', + template: ''' +

{{title}}

+ ''', + directives: const [HeroesComponent], + providers: const [ +// #enddocregion + ROUTER_PROVIDERS, +// #docregion + HeroService + ]) +class AppComponent { + String title = 'Tour of Heroes'; +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/app_component_2.dart b/public/docs/_examples/toh-5/dart/lib/app_component_2.dart new file mode 100644 index 0000000000..d0b6854c0f --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/app_component_2.dart @@ -0,0 +1,32 @@ +// #docplaster +// #docregion +import 'package:angular2/angular2.dart'; +// #docregion import-router +import 'package:angular2/router.dart'; +// #enddocregion import-router + +import 'hero_service.dart'; +import 'heroes_component.dart'; + +@Component( + selector: 'my-app', +// #docregion template + template: ''' +

{{title}}

+ Heroes + ''', +// #enddocregion template + // #docregion directives-and-providers + directives: const [ROUTER_DIRECTIVES], + providers: const [ROUTER_PROVIDERS, HeroService] + // #enddocregion directives-and-providers +) +// #docregion route-config +@RouteConfig(const [ + const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent) +]) +// #enddocregion route-config +class AppComponent { + String title = 'Tour of Heroes'; +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.css b/public/docs/_examples/toh-5/dart/lib/dashboard_component.css new file mode 100644 index 0000000000..ce6e963a5f --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.css @@ -0,0 +1,63 @@ +/* #docplaster */ +/* #docregion */ +[class*='col-'] { + float: left; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +[class*='col-'] { + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; +} +.grid { + margin: 0; +} +.col-1-4 { + width: 25%; +} +.module { + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; +} +h4 { + position: relative; +} +.module:hover { + background-color: #EEE; + cursor: pointer; + color: #607d8b; +} +.grid-pad { + padding: 10px 0; +} +.grid-pad > [class*='col-']:last-of-type { + padding-right: 20px; +} +@media (max-width: 600px) { + .module { + font-size: 10px; + max-height: 75px; } +} +@media (max-width: 1024px) { + .grid { + margin: 0; + } + .module { + min-width: 60px; + } +} +/* #enddocregion */ diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart new file mode 100644 index 0000000000..bd5d6f2caf --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart @@ -0,0 +1,43 @@ +// #docplaster +// #docregion +import 'package:angular2/angular2.dart'; +// #docregion import-router +import 'package:angular2/router.dart'; +// #enddocregion import-router + +import 'hero.dart'; +import 'hero_service.dart'; + +@Component( + selector: 'my-dashboard', + // #docregion template-url + templateUrl: 'dashboard_component.html', + // #enddocregion template-url + // #docregion css + styleUrls: const ['dashboard_component.css'] + // #enddocregion css +) +// #docregion component +class DashboardComponent implements OnInit { + List heroes; +// #docregion ctor + final Router _router; + final HeroService _heroService; + + DashboardComponent(this._heroService, this._router); +// #enddocregion ctor + + ngOnInit() async => + heroes = (await _heroService.getHeroes()).getRange(1, 5).toList(); + + // #docregion goto-detail + gotoDetail(Hero hero) { + var link = [ + 'HeroDetail', + {'id': hero.id.toString()} + ]; + _router.navigate(link); + } +// #enddocregion goto-detail +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.html b/public/docs/_examples/toh-5/dart/lib/dashboard_component.html new file mode 100644 index 0000000000..e6d5afd974 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.html @@ -0,0 +1,11 @@ + +

Top Heroes

+
+ +
+ +
+

{{hero.name}}

+
+
+
diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart new file mode 100644 index 0000000000..0839105b8c --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component_1.dart @@ -0,0 +1,8 @@ +// #docregion +import 'package:angular2/angular2.dart'; + +@Component( + selector: 'my-dashboard', + template: '

My Dashboard

' +) +class DashboardComponent {} diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart new file mode 100644 index 0000000000..a91eddf22c --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart @@ -0,0 +1,25 @@ +// #docplaster +// #docregion imports +import 'package:angular2/angular2.dart'; + +import 'hero.dart'; +import 'hero_service.dart'; +// #enddocregion imports + +// #docregion component +@Component( + selector: 'my-dashboard', + templateUrl: 'dashboard_component.html' +) +class DashboardComponent implements OnInit { + List heroes; + final HeroService _heroService; + + DashboardComponent(this._heroService); + + ngOnInit() async => + heroes = (await _heroService.getHeroes()).getRange(1, 5).toList(); + + gotoDetail(){ /* not implemented yet */} +} +// #enddocregion component diff --git a/public/docs/_examples/toh-5/dart/lib/hero.dart b/public/docs/_examples/toh-5/dart/lib/hero.dart new file mode 100644 index 0000000000..d62b733142 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/hero.dart @@ -0,0 +1,6 @@ +class Hero { + final int id; + String name; + + Hero(this.id, this.name); +} \ No newline at end of file diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.css b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.css new file mode 100644 index 0000000000..ab2437efd8 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.css @@ -0,0 +1,30 @@ +/* #docregion */ +label { + display: inline-block; + width: 3em; + margin: .5em 0; + color: #607D8B; + font-weight: bold; +} +input { + height: 2em; + font-size: 1em; + padding-left: .4em; +} +button { + margin-top: 20px; + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} +button:disabled { + background-color: #eee; + color: #ccc; + cursor: auto; +} diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart new file mode 100644 index 0000000000..c92b9981d6 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.dart @@ -0,0 +1,56 @@ +// #docplaster +// #docregion +// #docregion v2 +import 'dart:html'; + +// #docregion import-oninit +import 'package:angular2/angular2.dart'; +// #enddocregion import-oninit +// #docregion import-route-params +import 'package:angular2/router.dart'; +// #enddocregion import-route-params + +import 'hero.dart'; +// #docregion import-hero-service +import 'hero_service.dart'; +// #enddocregion import-hero-service + +// #docregion extract-template +@Component( + selector: 'my-hero-detail', + // #docregion template-url + templateUrl: 'hero_detail_component.html', + // #enddocregion template-url +// #enddocregion v2 + styleUrls: const ['hero_detail_component.css'] +// #docregion v2 +) +// #enddocregion extract-template +// #docregion implement +class HeroDetailComponent implements OnInit { +// #enddocregion implement + Hero hero; +// #docregion ctor + final HeroService _heroService; + final RouteParams _routeParams; + + HeroDetailComponent(this._heroService, this._routeParams); +// #enddocregion ctor + +// #docregion ng-oninit + ngOnInit() async { + // #docregion get-id + var id = int.parse(_routeParams.get('id')); + // #enddocregion get-id + hero = await (_heroService.getHero(id)); + } +// #enddocregion ng-oninit + +// #docregion go-back + goBack() { + window.history.back(); + } +// #enddocregion go-back +} +// #enddocregion v2 +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/hero_detail_component.html b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.html new file mode 100644 index 0000000000..9b2adf5c1e --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/hero_detail_component.html @@ -0,0 +1,14 @@ + + +
+

{{hero.name}} details!

+
+ {{hero.id}}
+
+ + +
+ + + +
\ No newline at end of file diff --git a/public/docs/_examples/toh-5/dart/lib/hero_service.dart b/public/docs/_examples/toh-5/dart/lib/hero_service.dart new file mode 100644 index 0000000000..eb6cc9f7f0 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/hero_service.dart @@ -0,0 +1,27 @@ +// #docplaster + +// #docregion +import 'dart:async'; + +import 'package:angular2/angular2.dart'; + +import 'hero.dart'; +import 'mock_heroes.dart'; + +@Injectable() +class HeroService { + Future> getHeroes() async => HEROES; + + // See the "Take it slow" appendix + Future> getHeroesSlowly() { + return new Future>.delayed( + const Duration(seconds: 2), () => HEROES // 2 seconds + ); + } + +//#docregion get-hero + Future getHero(int id) async => + HEROES.where((hero) => hero.id == id).first; +//#enddocregion get-hero +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.css b/public/docs/_examples/toh-5/dart/lib/heroes_component.css new file mode 100644 index 0000000000..d939ab565d --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/heroes_component.css @@ -0,0 +1,59 @@ +.selected { + background-color: #CFD8DC !important; + color: white; +} +.heroes { + margin: 0 0 2em 0; + list-style-type: none; + padding: 0; + width: 10em; +} +.heroes li { + cursor: pointer; + position: relative; + left: 0; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; +} +.heroes li:hover { + color: #607D8B; + background-color: #DDD; + left: .1em; +} +.heroes li.selected:hover { + background-color: #BBD8DC !important; + color: white; +} +.heroes .text { + position: relative; + top: -3px; +} +.heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0 0 4px; +} +button { + font-family: Arial; + background-color: #eee; + border: none; + padding: 5px 10px; + border-radius: 4px; + cursor: pointer; + cursor: hand; +} +button:hover { + background-color: #cfd8dc; +} diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.dart b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart new file mode 100644 index 0000000000..2cfc0fcbab --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/heroes_component.dart @@ -0,0 +1,51 @@ +// #docplaster +// #docregion +import 'dart:async'; + +import 'package:angular2/angular2.dart'; +import 'package:angular2/router.dart'; + +import 'hero.dart'; +import 'hero_detail_component.dart'; +import 'hero_service.dart'; + +// #docregion metadata +// #docregion heroes-component-renaming +@Component( + selector: 'my-heroes', +// #enddocregion heroes-component-renaming + templateUrl: 'heroes_component.html', + styleUrls: const ['heroes_component.css'], + directives: const [HeroDetailComponent] +// #docregion heroes-component-renaming +) +// #enddocregion heroes-component-renaming +// #enddocregion metadata +// #docregion class +// #docregion heroes-component-renaming +class HeroesComponent implements OnInit { +// #enddocregion heroes-component-renaming + final Router _router; + final HeroService _heroService; + List heroes; + Hero selectedHero; + + HeroesComponent(this._heroService, this._router); + + Future getHeroes() async { + heroes = await _heroService.getHeroes(); + } + + void ngOnInit() { + getHeroes(); + } + + void onSelect(Hero hero) { selectedHero = hero; } + + Future gotoDetail() => + _router.navigate(['HeroDetail', {'id': selectedHero.id.toString()}]); +// #docregion heroes-component-renaming +} +// #enddocregion heroes-component-renaming +// #enddocregion class +// #enddocregion diff --git a/public/docs/_examples/toh-5/dart/lib/heroes_component.html b/public/docs/_examples/toh-5/dart/lib/heroes_component.html new file mode 100644 index 0000000000..435dd8a5f4 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/heroes_component.html @@ -0,0 +1,21 @@ + + +

My Heroes

+
    +
  • + {{hero.id}} {{hero.name}} +
  • +
+ +
+

+ + {{selectedHero.name | uppercase}} is my hero + +

+ +
+ + diff --git a/public/docs/_examples/toh-5/dart/lib/mock_heroes.dart b/public/docs/_examples/toh-5/dart/lib/mock_heroes.dart new file mode 100644 index 0000000000..ee46fa86fe --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/mock_heroes.dart @@ -0,0 +1,14 @@ +import 'hero.dart'; + +final List HEROES = [ + new Hero(11, "Mr. Nice"), + new Hero(12, "Narco"), + new Hero(13, "Bombasto"), + new Hero(14, "Celeritas"), + new Hero(15, "Magneta"), + new Hero(16, "RubberMan"), + new Hero(17, "Dynama"), + new Hero(18, "Dr IQ"), + new Hero(19, "Magma"), + new Hero(20, "Tornado") +]; \ No newline at end of file diff --git a/public/docs/_examples/toh-5/dart/pubspec.yaml b/public/docs/_examples/toh-5/dart/pubspec.yaml new file mode 100644 index 0000000000..9e83a56a2a --- /dev/null +++ b/public/docs/_examples/toh-5/dart/pubspec.yaml @@ -0,0 +1,18 @@ +# #docregion +name: angular2_tour_of_heroes +description: Tour of Heroes 5 +version: 0.0.1 +environment: + sdk: '>=1.13.0 <2.0.0' +dependencies: + angular2: 2.0.0-beta.9 + browser: ^0.10.0 + dart_to_js_script_rewriter: ^0.1.0+4 +transformers: +- angular2: + platform_directives: package:angular2/common.dart#COMMON_DIRECTIVES + platform_pipes: package:angular2/common.dart#COMMON_PIPES + entry_points: web/main.dart +- dart_to_js_script_rewriter +- $dart2js: + checked: true diff --git a/public/docs/_examples/toh-5/dart/web/index.html b/public/docs/_examples/toh-5/dart/web/index.html new file mode 100644 index 0000000000..db501e102e --- /dev/null +++ b/public/docs/_examples/toh-5/dart/web/index.html @@ -0,0 +1,24 @@ + + + + + + + + + Angular 2 Tour of Heroes + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-5/dart/web/main.dart b/public/docs/_examples/toh-5/dart/web/main.dart new file mode 100644 index 0000000000..5983c199f7 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/web/main.dart @@ -0,0 +1,7 @@ +import 'package:angular2/bootstrap.dart'; + +import 'package:angular2_tour_of_heroes/app_component.dart'; + +main() { + bootstrap(AppComponent); +} diff --git a/public/docs/dart/latest/tutorial/index.jade b/public/docs/dart/latest/tutorial/index.jade index 6778b6af28..31520de5ac 100644 --- a/public/docs/dart/latest/tutorial/index.jade +++ b/public/docs/dart/latest/tutorial/index.jade @@ -1 +1,13 @@ -!= partial("../../../_includes/_ts-temp") +include ../_util-fns + +:marked + We're working on the Dart version of this case study. + In the meantime, please see these resources: + + * [Introduction](/docs/ts/latest/tutorial/index.html): + The TypeScript version of this chapter + + * [Dart source code](https://github.com/angular/angular.io/tree/master/public/docs/_examples/toh-5/dart): + A preliminary Dart version of the Tour of Heroes app, + featuring the hero editor, master/detail views, + multiple components, services, and routing diff --git a/public/docs/dart/latest/tutorial/toh-pt1.jade b/public/docs/dart/latest/tutorial/toh-pt1.jade index 6778b6af28..d15c0fe744 100644 --- a/public/docs/dart/latest/tutorial/toh-pt1.jade +++ b/public/docs/dart/latest/tutorial/toh-pt1.jade @@ -1 +1,14 @@ -!= partial("../../../_includes/_ts-temp") +include ../_util-fns + +:marked + We're working on the Dart version of this case study. + In the meantime, please see these resources: + + * [The Hero Editor](/docs/ts/latest/tutorial/toh-pt1.html): + The TypeScript version of this chapter + + * [Dart source code](https://github.com/angular/angular.io/tree/master/public/docs/_examples/toh-5/dart): + A preliminary Dart version of the Tour of Heroes app, + featuring the hero editor, a master/detail page, + multiple components, services, and routing + diff --git a/public/docs/dart/latest/tutorial/toh-pt2.jade b/public/docs/dart/latest/tutorial/toh-pt2.jade index 6778b6af28..76a5523647 100644 --- a/public/docs/dart/latest/tutorial/toh-pt2.jade +++ b/public/docs/dart/latest/tutorial/toh-pt2.jade @@ -1 +1,14 @@ -!= partial("../../../_includes/_ts-temp") +include ../_util-fns + +:marked + We're working on the Dart version of this case study. + In the meantime, please see these resources: + + * [Master/Detail](/docs/ts/latest/tutorial/toh-pt2.html): + The TypeScript version of this chapter + + * [Dart source code](https://github.com/angular/angular.io/tree/master/public/docs/_examples/toh-5/dart): + A preliminary Dart version of the Tour of Heroes app, + featuring the hero editor, a master/detail page, + multiple components, services, and routing + diff --git a/public/docs/dart/latest/tutorial/toh-pt3.jade b/public/docs/dart/latest/tutorial/toh-pt3.jade index 6778b6af28..c415f0f53e 100644 --- a/public/docs/dart/latest/tutorial/toh-pt3.jade +++ b/public/docs/dart/latest/tutorial/toh-pt3.jade @@ -1 +1,14 @@ -!= partial("../../../_includes/_ts-temp") +include ../_util-fns + +:marked + We're working on the Dart version of this case study. + In the meantime, please see these resources: + + * [Multiple Components](/docs/ts/latest/tutorial/toh-pt3.html): + The TypeScript version of this chapter + + * [Dart source code](https://github.com/angular/angular.io/tree/master/public/docs/_examples/toh-5/dart): + A preliminary Dart version of the Tour of Heroes app, + featuring the hero editor, a master/detail page, + multiple components, services, and routing + diff --git a/public/docs/dart/latest/tutorial/toh-pt4.jade b/public/docs/dart/latest/tutorial/toh-pt4.jade index 6778b6af28..7c488613dd 100644 --- a/public/docs/dart/latest/tutorial/toh-pt4.jade +++ b/public/docs/dart/latest/tutorial/toh-pt4.jade @@ -1 +1,14 @@ -!= partial("../../../_includes/_ts-temp") +include ../_util-fns + +:marked + We're working on the Dart version of this case study. + In the meantime, please see these resources: + + * [Services](/docs/ts/latest/tutorial/toh-pt4.html): + The TypeScript version of this chapter + + * [Dart source code](https://github.com/angular/angular.io/tree/master/public/docs/_examples/toh-5/dart): + A preliminary Dart version of the Tour of Heroes app, + featuring the hero editor, a master/detail page, + multiple components, services, and routing + diff --git a/public/docs/dart/latest/tutorial/toh-pt5-NEW.jade b/public/docs/dart/latest/tutorial/toh-pt5-NEW.jade new file mode 100644 index 0000000000..685048157c --- /dev/null +++ b/public/docs/dart/latest/tutorial/toh-pt5-NEW.jade @@ -0,0 +1,699 @@ +include ../_util-fns + +:marked + # Routing Around the App + We received new requirements for our Tour of Heroes application: + * add a *Dashboard* view. + * navigate between the *Heroes* and *Dashboard* views. + * clicking on a hero in either view navigates to a detail view of the selected hero. + * clicking a *deep link* in an email opens the detail view for a particular hero; + + When we’re done, users will be able to navigate the app like this: +figure.image-display + img(src='/resources/images/devguide/toh/nav-diagram.png' alt="View navigations") +:marked + We'll add Angular’s *Component Router* to our app to satisfy these requirements. +.l-sub-section + :marked + The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail + than we will in this tour. +:marked + [Run the live example](/resources/live-examples/toh-5/ts/plnkr.html). +.l-sub-section + img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px") + :marked + To see the URL changes in the browser address bar, + pop out the preview window by clicking the blue 'X' button in the upper right corner: + +.l-main-section +:marked + ## Where We Left Off + Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service + and hero detail component. If not, we’ll need to go back and follow the previous chapters. + +.filetree + .file angular2-tour-of-heroes + .children + .file lib + .children + .file app_component.dart + .file hero.dart + .file hero_detail_component.dart + .file hero_service.dart + .file mock_heroes.dart + .file web + .children + .file index.html + .file main.dart + .file styles.css + .file pubspec.yaml +:marked + ### Run the app + Open a terminal/console window and enter the following command to + start the server: + +code-example(format="." language="bash"). + pub serve + +:marked + The application runs by default on `localhost:8080`. + + ## Action plan + Here's our plan + + * turn `AppComponent` into an application shell that only handles navigation. + * relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent` + * add routing + * create a new `DashboardComponent` + * tie the *Dashboard* into the navigation structure. + +.l-sub-section + :marked + *Routing* is another name for *navigation*. The *router* is the mechanism for navigating from view to view. + +.l-main-section +:marked + ## Splitting the *AppComponent* + + Our current app loads `AppComponent` and immediately displays the list of heroes. + + Our revised app should present a shell with a choice of views (*Dashboard* and *Heroes*) and then default to one of them. + + The `AppComponent` should only handle navigation. + Let's move the display of *Heroes* out of `AppComponent` and into its own `HeroesComponent`. + + ### *HeroesComponent* + `AppComponent` is already dedicated to *Heroes*. + Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent` + and create a new `AppComponent` shell separately. + + The steps are: + * rename `app_component.dart` file to `heroes_component.dart`. + * rename the `AppComponent` class to `HeroesComponent`. + * rename the selector `my-app` to `my-heroes`. + +:marked ++makeExample('toh-5/dart/lib/heroes_component.dart', 'heroes-component-renaming', 'lib/heroes_component.dart (renaming)')(format=".") + +:marked + ## Create *AppComponent* + The new `AppComponent` will be the application shell. + It will have some navigation links at the top and a display area below for the pages we navigate to. + + The initial steps are: + + * create a new file named `app_component.dart`. + * define an `AppComponent` class. + * expose an application `title` property. + * add the `@Component` metadata decorator above the class with a `my-app` selector. + * add a template with `

` tags surrounding a binding to the `title` property. + * add the `` tags to the template so we still see the heroes. + * add the `HeroesComponent` to the `directives` array so Angular recognizes the `` tags. + * add the `HeroService` to the `providers` array because we'll need it in every other view. + * add the supporting `import` statements. + + Our first draft looks like this: ++makeExample('toh-5/dart/lib/app_component_1.dart', null, 'lib/app_component.dart (v1)') +:marked +.callout.is-critical + header Remove HeroService from the HeroesComponent providers + :marked + Go back to the `HeroesComponent` and **remove the `HeroService`** from its `providers` array. + We are *promoting* this service from the `HeroesComponent` to the `AppComponent`. + We ***do not want two copies*** of this service at two different levels of our app. +:marked + The app still runs and still displays heroes. + Our refactoring of `AppComponent` into a new `AppComponent` and a `HeroesComponent` worked! + We have done no harm. + +:marked + ## Add Routing + + We're ready to take the next step. + Instead of displaying heroes automatically, we'd like to show them *after* the user clicks a button. + In other words, we'd like to navigate to the list of heroes. + + We'll need the Angular *Component Router*. + + ### Include the Router Library + Not all apps need routing which is why the Angular *Component Router* is in a separate, optional module library. + +// Our Tour of Heroes needs routing, +// so we load the library in the `index.html` in a script tag immediately *after* the angular script itself. +//+makeExample('toh-5/dart/web/index.html', 'router', 'index.html (router)')(format=".") +:marked + While we're in `index.html`, we add `` at the top of the `` section. ++makeExample('toh-5/dart/web/index.html', 'base-href', 'index.html (base href)')(format=".") +.callout.is-important + header base href is essential + :marked + See the *base href* section of the [Router](../guide/router.html#!#base-href) chapter to learn why this matters. +:marked + ### Make the router available. + The *Component Router* is a service. Like any service, we have to import it and make it + available to the application by adding it to the `providers` array. + + The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`), + and a configuration decorator (`RouteConfig`). We'll import them all together: ++makeExample('toh-5/dart/lib/app_component_2.dart', 'import-router', 'app_component.dart (router imports)')(format=".") +:marked + Next we update the `directives` and `providers` metadata arrays to *include* the router assets. ++makeExample('toh-5/dart/lib/app_component_2.dart', 'directives-and-providers', 'app_component.dart (directives and providers)')(format=".") +:marked + Notice that we also removed the `HeroesComponent` from the `directives` array. + `AppComponent` no longer shows heroes; that will be the router's job. + We'll soon remove `` from the template too. + + ### Add and configure the router + + The `AppComponent` doesn't have a router yet. We'll use the `@RouteConfig` decorator to simultaneously + (a) assign a router to the component and (b) configure that router with *routes*. + + *Routes* tell the router which views to display when a user clicks a link or + pastes a URL into the browser address bar. + + Let's define our first route, a route to the `HeroesComponent`. ++makeExample('toh-5/dart/lib/app_component_2.dart', 'route-config', 'app_component.dart (RouteConfig for heroes)')(format=".") +:marked + `@RouteConfig` takes an array of *Route* definitions. + We have only one route definition at the moment but rest assured, we'll add more. + + This *route definition* has three parts: + * **path**: the router matches this route's path to the URL in the browser address bar (`/heroes`). + + * **name**: the official name of the route; it *must* begin with a capital letter to avoid confusion with the *path* (`Heroes`). + + * **component**: the component that the router should create when navigating to this route (`HeroesComponent`). + +.l-sub-section + :marked + Learn more about defining routes with @RouteConfig in the [Routing](../guide/router.html) chapter. +:marked + ### Router Outlet + + If we paste the path, `/heroes`, into the browser address bar, + the router should match it to the `'Heroes'` route and display the `HeroesComponent`. + But where? + + We have to ***tell it where*** by adding `` marker tags to the bottom of the template. + `RouterOutlet` is one of the `ROUTER_DIRECTIVES`. + The router displays each component immediately below the `` as we navigate through the application. + + ### Router Links + We don't really expect users to paste a route URL into the address bar. + We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`. + + The revised template looks like this: ++makeExample('toh-5/dart/lib/app_component_2.dart', 'template', 'app_component.dart (template for Heroes)')(format=".") +:marked + Notice the `[routerLink]` binding in the anchor tag. + We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to an array + that tells the router where to navigate when the user clicks the link. + + We define a *routing instruction* with a *link parameters array*. + The array only has one element in our little sample, the quoted ***name* of the route** to follow. + Looking back at the route configuration, we confirm that `'Heroes'` is the name of the route to the `HeroesComponent`. +.l-sub-section + :marked + Learn about the *link parameters array* in the [Routing](../guide/router.html#link-parameters-array) chapter. +:marked + Refresh the browser. We see only the app title. We don't see the heroes list. +.l-sub-section + :marked + The browser's address bar shows `/`. + The route path to `HeroesComponent` is `/heroes`, not `/`. + We don't have a route that matches the path `/`, so there is nothing to show. + That's something we'll want to fix. +:marked + We click the "Heroes" navigation link, the browser bar updates to `/heroes`, + and now we see the list of heroes. We are navigating at last! + + At this stage, our `AppComponent` looks like this. ++makeExample('toh-5/dart/lib/app_component_2.dart',null, 'lib/app_component.dart (v2)') +:marked + The *AppComponent* is now attached to a router and displaying routed views. + For this reason and to distinguish it from other kinds of components, + we call this type of component a *Router Component*. + + +:marked + ## Add a *Dashboard* + Routing only makes sense when we have multiple views. We need another view. + + Create a placeholder `DashboardComponent` that gives us something to navigate to and from. ++makeExample('toh-5/dart/lib/dashboard_component_1.dart',null, 'lib/dashboard_component.dart (v1)')(format=".") +:marked + We’ll come back and make it more useful later. + + ### Configure the dashboard route + Go back to `app_component.dart` and teach it to navigate to the dashboard. + + Import the `DashboardComponent` so we can reference it in the dashboard route definition. + + Add the following `'Dashboard'` route definition to the `@RouteConfig` array of definitions. ++makeExample('toh-5/dart/lib/app_component.dart','dashboard-route', 'app_component.dart (Dashboard Route)')(format=".") +.l-sub-section + :marked + **useAsDefault** + + We want the app to show the dashboard when it starts and + we want to see a nice URL in the browser address bar that says `/dashboard`. + Remember that the browser launches with `/` in the address bar. + We don't have a route for that path and we'd rather not create one. + + Fortunately we can add the `useAsDefault: true` property to the *route definition* and the + router will display the dashboard when the browser URL doesn't match an existing route. +:marked + Finally, add a dashboard navigation link to the template, just above the *Heroes* link. + ++makeExample('toh-5/dart/lib/app_component.dart','template', 'app_component.dart (template)')(format=".") +.l-sub-section + :marked + We nestled the two links within `