From dcd02b4e0db83f9bb42f47568223d3426f13966a Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 17 Jun 2016 15:57:35 -0700 Subject: [PATCH 1/2] docs(toh-6/dart): first edition of prose and example code NOTE: this PR depends on #1686. Dart prose and example match TS except that: - No child-to-parent event emission occurs. - Support for Add Hero is added as an unconditional feature of the Heroes view. - http `_post` takes only a name - http `delete` takes only a hero id. - The Dart in-memory-data-service has been dropped in favor of an implementation based on the "standard" `http.testing.MockClient` class. --- .../docs/_examples/toh-6/dart/.docsync.json | 5 + .../toh-6/dart/lib/app_component.css | 29 ++++ .../toh-6/dart/lib/app_component.dart | 45 ++++++ .../toh-6/dart/lib/dashboard_component.css | 61 ++++++++ .../toh-6/dart/lib/dashboard_component.dart | 47 ++++++ .../toh-6/dart/lib/dashboard_component.html | 11 ++ .../docs/_examples/toh-6/dart/lib/hero.dart | 14 ++ .../toh-6/dart/lib/hero_detail_component.css | 30 ++++ .../toh-6/dart/lib/hero_detail_component.dart | 61 ++++++++ .../toh-6/dart/lib/hero_detail_component.html | 15 ++ .../toh-6/dart/lib/hero_service.dart | 91 ++++++++++++ .../toh-6/dart/lib/heroes_component.css | 59 ++++++++ .../toh-6/dart/lib/heroes_component.dart | 69 +++++++++ .../toh-6/dart/lib/heroes_component.html | 31 ++++ .../dart/lib/in_memory_data_service.dart | 64 ++++++++ public/docs/_examples/toh-6/dart/pubspec.yaml | 28 ++++ .../docs/_examples/toh-6/dart/web/index.html | 18 +++ .../docs/_examples/toh-6/dart/web/main.dart | 24 +++ .../docs/_examples/toh-6/dart/web/sample.css | 7 + public/docs/dart/latest/tutorial/toh-pt6.jade | 140 +++++++++++++++++- 20 files changed, 848 insertions(+), 1 deletion(-) create mode 100644 public/docs/_examples/toh-6/dart/.docsync.json create mode 100644 public/docs/_examples/toh-6/dart/lib/app_component.css create mode 100644 public/docs/_examples/toh-6/dart/lib/app_component.dart create mode 100644 public/docs/_examples/toh-6/dart/lib/dashboard_component.css create mode 100644 public/docs/_examples/toh-6/dart/lib/dashboard_component.dart create mode 100644 public/docs/_examples/toh-6/dart/lib/dashboard_component.html create mode 100644 public/docs/_examples/toh-6/dart/lib/hero.dart create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_detail_component.css create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_detail_component.html create mode 100644 public/docs/_examples/toh-6/dart/lib/hero_service.dart create mode 100644 public/docs/_examples/toh-6/dart/lib/heroes_component.css create mode 100644 public/docs/_examples/toh-6/dart/lib/heroes_component.dart create mode 100644 public/docs/_examples/toh-6/dart/lib/heroes_component.html create mode 100644 public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart create mode 100644 public/docs/_examples/toh-6/dart/pubspec.yaml create mode 100644 public/docs/_examples/toh-6/dart/web/index.html create mode 100644 public/docs/_examples/toh-6/dart/web/main.dart create mode 100644 public/docs/_examples/toh-6/dart/web/sample.css diff --git a/public/docs/_examples/toh-6/dart/.docsync.json b/public/docs/_examples/toh-6/dart/.docsync.json new file mode 100644 index 0000000000..29f01f6648 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/.docsync.json @@ -0,0 +1,5 @@ +{ + "title": "Tour of Heroes: HTTP", + "docPart": "tutorial", + "docHref": "toh-pt6.html" +} diff --git a/public/docs/_examples/toh-6/dart/lib/app_component.css b/public/docs/_examples/toh-6/dart/lib/app_component.css new file mode 100644 index 0000000000..f4e8082ea1 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/app_component.css @@ -0,0 +1,29 @@ +/* #docregion */ +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; +} diff --git a/public/docs/_examples/toh-6/dart/lib/app_component.dart b/public/docs/_examples/toh-6/dart/lib/app_component.dart new file mode 100644 index 0000000000..ecf2bf4f3c --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/app_component.dart @@ -0,0 +1,45 @@ +// #docplaster +// #docregion +import 'package:angular2/core.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'; +} diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.css b/public/docs/_examples/toh-6/dart/lib/dashboard_component.css new file mode 100644 index 0000000000..f6263074f0 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.css @@ -0,0 +1,61 @@ +/* #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; + } +} diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart new file mode 100644 index 0000000000..ff0fb8c0d1 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart @@ -0,0 +1,47 @@ +// #docplaster +// #docregion +import 'dart:async'; + +import 'package:angular2/core.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 + + Future ngOnInit() async { + heroes = (await _heroService.getHeroes()).skip(1).take(4).toList(); + } + + // #docregion goto-detail + void gotoDetail(Hero hero) { + var link = [ + 'HeroDetail', + {'id': hero.id.toString()} + ]; + _router.navigate(link); + } +// #enddocregion goto-detail +} diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.html b/public/docs/_examples/toh-6/dart/lib/dashboard_component.html new file mode 100644 index 0000000000..7133c10ada --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.html @@ -0,0 +1,11 @@ + +

Top Heroes

+
+ +
+ +
+

{{hero.name}}

+
+
+
diff --git a/public/docs/_examples/toh-6/dart/lib/hero.dart b/public/docs/_examples/toh-6/dart/lib/hero.dart new file mode 100644 index 0000000000..bc9a33b8d9 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/hero.dart @@ -0,0 +1,14 @@ +// #docregion +class Hero { + final int id; + String name; + + Hero(this.id, this.name); + + factory Hero.fromJson(Map hero) => + new Hero(_toInt(hero['id']), hero['name']); + + Map toJson() => {'id': id, 'name': name}; +} + +int _toInt(id) => id is int ? id : int.parse(id); diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.css b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.css new file mode 100644 index 0000000000..ab2437efd8 --- /dev/null +++ b/public/docs/_examples/toh-6/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-6/dart/lib/hero_detail_component.dart b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart new file mode 100644 index 0000000000..39f9f531f5 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.dart @@ -0,0 +1,61 @@ +// #docplaster +// #docregion , v2 +import 'dart:async'; +import 'dart:html'; + +// #docregion import-oninit +import 'package:angular2/core.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, 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 + Future ngOnInit() async { + // #docregion get-id + var idString = _routeParams.get('id'); + var id = int.parse(idString, onError: (_) => null); + // #enddocregion get-id + if (id != null) hero = await (_heroService.getHero(id)); + } + // #enddocregion ng-oninit + + // #docregion save + Future save() async { + await _heroService.save(hero); + goBack(); + } + // #enddocregion save + + // #docregion go-back + void goBack() { + window.history.back(); + } + // #enddocregion go-back +} diff --git a/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html new file mode 100644 index 0000000000..d15546af74 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/hero_detail_component.html @@ -0,0 +1,15 @@ + + +
+

{{hero.name}} details!

+
+ {{hero.id}}
+
+ + +
+ + + + +
diff --git a/public/docs/_examples/toh-6/dart/lib/hero_service.dart b/public/docs/_examples/toh-6/dart/lib/hero_service.dart new file mode 100644 index 0000000000..7a15c6473f --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/hero_service.dart @@ -0,0 +1,91 @@ +// #docregion +import 'dart:async'; +import 'dart:convert'; + +import 'package:angular2/core.dart'; +import 'package:http/http.dart'; + +import 'hero.dart'; + +@Injectable() +class HeroService { + // #docregion post + static final _headers = {'Content-Type': 'application/json'}; + // #enddocregion post + // #docregion getHeroes + static const _heroesUrl = 'app/heroes'; // URL to web API + + final Client _http; + + HeroService(this._http); + + Future> getHeroes() async { + try { + final response = await _http.get(_heroesUrl); + final heroes = _extractData(response) + .map((value) => new Hero.fromJson(value)) + .toList(); + return heroes; + // #docregion catch + } catch (e) { + throw _handleError(e); + } + // #enddocregion catch + } + + // #docregion extract-data + dynamic _extractData(Response resp) => JSON.decode(resp.body)['data']; + // #enddocregion extract-data, getHeroes + + Future getHero(int id) async => + (await getHeroes()).firstWhere((hero) => hero.id == id); + + // #docregion save + Future save(dynamic heroOrName) => + heroOrName is Hero ? _put(heroOrName) : _post(heroOrName); + // #enddocregion save + + // #docregion handleError + Exception _handleError(dynamic e) { + print(e); // for demo purposes only + return new Exception('Server error; cause: $e'); + } + // #enddocregion handleError + + // #docregion post + Future _post(String name) async { + try { + final response = await _http.post(_heroesUrl, + headers: _headers, body: JSON.encode({'name': name})); + return new Hero.fromJson(_extractData(response)); + } catch (e) { + throw _handleError(e); + } + } + // #enddocregion post + + // #docregion put + Future _put(Hero hero) async { + try { + var url = '$_heroesUrl/${hero.id}'; + final response = + await _http.put(url, headers: _headers, body: JSON.encode(hero)); + return new Hero.fromJson(_extractData(response)); + } catch (e) { + throw _handleError(e); + } + } + // #enddocregion put + + // #docregion delete + Future delete(int id) async { + try { + var url = '$_heroesUrl/$id'; + await _http.delete(url, headers: _headers); + } catch (e) { + throw _handleError(e); + } + } + // #enddocregion delete + +} diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.css b/public/docs/_examples/toh-6/dart/lib/heroes_component.css new file mode 100644 index 0000000000..35e45af98d --- /dev/null +++ b/public/docs/_examples/toh-6/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: 15em; +} +.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-6/dart/lib/heroes_component.dart b/public/docs/_examples/toh-6/dart/lib/heroes_component.dart new file mode 100644 index 0000000000..4cfc0c427e --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.dart @@ -0,0 +1,69 @@ +// #docplaster +// #docregion +import 'dart:async'; + +import 'package:angular2/core.dart'; +import 'package:angular2/router.dart'; + +import 'hero.dart'; +import 'hero_detail_component.dart'; +import 'hero_service.dart'; + +@Component( + selector: 'my-heroes', + templateUrl: 'heroes_component.html', + styleUrls: const ['heroes_component.css'], + directives: const [HeroDetailComponent]) +class HeroesComponent implements OnInit { + final Router _router; + final HeroService _heroService; + List heroes; + Hero selectedHero; + // #docregion error + String errorMessage; + // #enddocregion error + + HeroesComponent(this._heroService, this._router); + + // #docregion addHero + Future addHero(String name) async { + name = name.trim(); + if (name.isEmpty) return; + try { + heroes.add(await _heroService.save(name)); + } catch (e) { + errorMessage = e.toString(); + } + } + // #enddocregion addHero + + // #docregion deleteHero + Future deleteHero(int id, event) async { + try { + event.stopPropagation(); + await _heroService.delete(id); + heroes.removeWhere((hero) => hero.id == id); + if (selectedHero?.id == id) selectedHero = null; + } catch (e) { + errorMessage = e.toString(); + } + } + // #enddocregion deleteHero + + 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()} + ]); +} diff --git a/public/docs/_examples/toh-6/dart/lib/heroes_component.html b/public/docs/_examples/toh-6/dart/lib/heroes_component.html new file mode 100644 index 0000000000..98f3db8442 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/heroes_component.html @@ -0,0 +1,31 @@ + + +

My Heroes

+ +
{{errorMessage}}
+
+ Name: + +
+ +
    +
  • + {{hero.id}} {{hero.name}} + + + +
  • +
+ +
+

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

+ +
diff --git a/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart b/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart new file mode 100644 index 0000000000..86aad3de53 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart @@ -0,0 +1,64 @@ +// #docregion +import 'dart:async'; +import 'dart:convert'; + +// #docregion init +import 'package:angular2/core.dart'; +import 'package:http/http.dart'; +import 'package:http/testing.dart'; + +import 'hero.dart'; + +@Injectable() +class InMemoryDataService extends MockClient { + static final _initialHeroes = [ + {'id': 11, 'name': 'Mr. Nice'}, + {'id': 12, 'name': 'Narco'}, + {'id': 13, 'name': 'Bombasto'}, + {'id': 14, 'name': 'Celeritas'}, + {'id': 15, 'name': 'Magneta'}, + {'id': 16, 'name': 'RubberMan'}, + {'id': 17, 'name': 'Dynama2'}, + {'id': 18, 'name': 'Dr IQ'}, + {'id': 19, 'name': 'Magma'}, + {'id': 20, 'name': 'Tornado'} + ]; + // #enddocregion init + + static final List _heroesDb = + _initialHeroes.map((json) => new Hero.fromJson(json)).toList(); + static int _nextId = 21; + + static Future _handler(Request request) async { + var data; + switch (request.method) { + case 'GET': + data = _heroesDb; + break; + case 'POST': + var name = JSON.decode(request.body)['name']; + var newHero = new Hero(_nextId++, name); + _heroesDb.add(newHero); + data = newHero; + break; + case 'PUT': + var heroChanges = new Hero.fromJson(JSON.decode(request.body)); + var targetHero = _heroesDb.firstWhere((h) => h.id == heroChanges.id); + targetHero.name = heroChanges.name; + data = targetHero; + break; + case 'DELETE': + var id = int.parse(request.url.pathSegments.last); + _heroesDb.removeWhere((hero) => hero.id == id); + // No data, so leave it as null. + break; + default: + throw 'Unimplemented HTTP method ${request.method}'; + } + return new Response(JSON.encode({'data': data}), 200, + headers: {'content-type': 'application/json'}); + } + + InMemoryDataService() : super(_handler); + // #docregion init +} diff --git a/public/docs/_examples/toh-6/dart/pubspec.yaml b/public/docs/_examples/toh-6/dart/pubspec.yaml new file mode 100644 index 0000000000..574758d902 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/pubspec.yaml @@ -0,0 +1,28 @@ +# #docregion , additions +name: angular2_tour_of_heroes + # #enddocregion additions +description: Tour of Heroes +version: 0.0.1 +environment: + sdk: '>=1.13.0 <2.0.0' + # #docregion additions +dependencies: + angular2: 2.0.0-beta.17 + # #enddocregion additions + browser: ^0.10.0 + dart_to_js_script_rewriter: ^1.0.1 + # #docregion additions + http: ^0.11.0 +transformers: +- angular2: + # #enddocregion additions + platform_directives: + - 'package:angular2/common.dart#COMMON_DIRECTIVES' + platform_pipes: + - 'package:angular2/common.dart#COMMON_PIPES' + # #docregion additions + entry_points: web/main.dart + resolved_identifiers: + BrowserClient: 'package:http/browser_client.dart' + Client: 'package:http/http.dart' +- dart_to_js_script_rewriter diff --git a/public/docs/_examples/toh-6/dart/web/index.html b/public/docs/_examples/toh-6/dart/web/index.html new file mode 100644 index 0000000000..be8fb7b42e --- /dev/null +++ b/public/docs/_examples/toh-6/dart/web/index.html @@ -0,0 +1,18 @@ + + + + + + Angular 2 Tour of Heroes + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-6/dart/web/main.dart b/public/docs/_examples/toh-6/dart/web/main.dart new file mode 100644 index 0000000000..e39cffce62 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/web/main.dart @@ -0,0 +1,24 @@ +// #docplaster +// #docregion final +// #docregion v1 +import 'package:angular2/core.dart'; +import 'package:angular2/platform/browser.dart'; +import 'package:http/http.dart'; +import 'package:angular2_tour_of_heroes/app_component.dart'; +// #enddocregion v1 +import 'package:angular2_tour_of_heroes/in_memory_data_service.dart'; + +void main() { + bootstrap(AppComponent, const [ + const Provider(Client, useClass: InMemoryDataService) + ]); +} +// #enddocregion final +/* +// #docregion v1 + +void main() { + bootstrap(AppComponent, const [BrowserClient]); +} +// #enddocregion v1 +*/ diff --git a/public/docs/_examples/toh-6/dart/web/sample.css b/public/docs/_examples/toh-6/dart/web/sample.css new file mode 100644 index 0000000000..6bbf5de8b7 --- /dev/null +++ b/public/docs/_examples/toh-6/dart/web/sample.css @@ -0,0 +1,7 @@ +/* #docregion */ +.error {color:red;} +button.delete-button { + float:right; + background-color: gray !important; + color:white; +} diff --git a/public/docs/dart/latest/tutorial/toh-pt6.jade b/public/docs/dart/latest/tutorial/toh-pt6.jade index 6778b6af28..a939923d2b 100644 --- a/public/docs/dart/latest/tutorial/toh-pt6.jade +++ b/public/docs/dart/latest/tutorial/toh-pt6.jade @@ -1 +1,139 @@ -!= partial("../../../_includes/_ts-temp") +extends ../../../ts/latest/tutorial/toh-pt6.jade + +block includes + include ../_util-fns + - var _Http = 'BrowserClient'; + - var _Angular_Http = 'Dart BrowserClient' + - var _httpUrl = 'https://pub.dartlang.org/packages/http' + - var _Angular_http_library = 'Dart http library' + - var _HTTP_PROVIDERS = 'BrowserClient' + - var _JSON_stringify = 'JSON.encode' + +block start-server-and-watch + :marked + ### Keep the app compiling and running + Open a terminal/console window. + Start the Dart compiler, watch for changes, and start our server by entering the command: + + code-example(language="bash"). + pub serve + +block http-library + :marked + We'll be using the !{_Angular_Http} to communicate with a server. + This class is exported by the !{_Angular_http_library}. + + ### Pubspec updates + + We need to add a package dependency for the !{_Angular_http_library}. + + We also need to inform the Dart Angular 2 Transformer that we will be using + `BrowserClient` (we'll defer explaining _why_ this extra configuration is + needed until the [HTTP client chapter](../guide/server-communication.html#!#http-providers)) + by means of the transformer's `resolved_identifiers` configuration parameter. + Since we will also be needing the !{_Angular_http_library} `Client` interface, we'll + add that now as well. + + Update `pubspec.yaml` to look like this (additions are highlighted): + + - var stylePattern = { pnk: /(http.*|resolved_identifiers:|Browser.*|Client.*)/gm }; + +makeExcerpt('pubspec.yaml', 'additions', null, stylePattern) + +block http-providers + :marked + Before our app can use `#{_Http}`, we have to register it as a service provider. + +block backend + :marked + We want to replace `BrowserClient`, the service that talks to the remote server, + with the in-memory web API service. + Our in-memory web API service, shown below, is implemented using the + standard `http` library `MockClient` class. + All `http` client implementations share a common `Client` interface, so + we'll have our app use the `Client` type so that we can freely switch between + implementations. + +block dont-be-distracted-by-backend-subst + //- N/A + +block get-heroes-details + :marked + We make an asynchronous call to `http.get()` which returns an HTTP + `Response`. The response payload (`body`) is decoded as JSON via the + `_extractData` helper method. + +block hero-detail-comp-extra-imports-and-vars + //- N/A + +block hero-detail-comp-updates + :marked + ### Edit in the *HeroDetailComponent* + + We already have `HeroDetailComponent` for viewing details about a specific hero. + Supporting edit functionality is natural extensions of the detail view, so we are able to reuse `HeroDetailComponent` with a few tweaks. + +block hero-detail-comp-save-and-goback + //- N/A + +block add-new-hero-via-detail-comp + //- N/A + +block heroes-comp-directives + //- N/A + +block heroes-comp-add + //- N/A + +block review + //- Not showing animated gif due to differences between TS and Dart implementations. + +block filetree + .filetree + .file angular2-tour-of-heroes + .children + .file lib + .children + .file app_component.dart + .file app_component.css + .file dashboard_component.css + .file dashboard_component.html + .file dashboard_component.dart + .file hero.dart + .file hero_detail_component.css + .file hero_detail_component.html + .file hero_detail_component.dart + .file hero_service.dart + .file heroes_component.css + .file heroes_component.html + .file heroes_component.dart + .file main.dart + .file in_memory_data_service.dart (new) + .file web + .children + .file main.dart + .file index.html + .file sample.css (new) + .file styles.css + .file pubspec.yaml + +block file-summary + +makeTabs( + `toh-6/dart/lib/hero.dart, + toh-6/dart/lib/hero_detail_component.dart, + toh-6/dart/lib/hero_detail_component.html, + toh-6/dart/lib/hero_service.dart, + toh-6/dart/lib/heroes_component.dart, + toh-6/dart/web/index.html, + toh-6/dart/web/main.dart, + toh-6/dart/web/sample.css`, + `,,,,,,final,`, + `lib/hero.dart, + lib/hero_detail_component.dart, + lib/hero_detail_component.html, + lib/hero_service.dart, + lib/heroes_component.dart, + web/index.html, + web/main.dart, + web/sample.css`) + + +makeExample('pubspec.yaml') From ef2695d381383fac55750b43f56e0cdec40e4a0c Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 28 Jun 2016 10:47:36 -0700 Subject: [PATCH 2/2] post-review changes --- .../docs/_examples/toh-6/dart/web/main.dart | 15 ++++++---- public/docs/dart/latest/tutorial/toh-pt6.jade | 30 ++++++++++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/public/docs/_examples/toh-6/dart/web/main.dart b/public/docs/_examples/toh-6/dart/web/main.dart index e39cffce62..1075856c61 100644 --- a/public/docs/_examples/toh-6/dart/web/main.dart +++ b/public/docs/_examples/toh-6/dart/web/main.dart @@ -3,22 +3,27 @@ // #docregion v1 import 'package:angular2/core.dart'; import 'package:angular2/platform/browser.dart'; -import 'package:http/http.dart'; import 'package:angular2_tour_of_heroes/app_component.dart'; // #enddocregion v1 +import 'package:http/http.dart'; import 'package:angular2_tour_of_heroes/in_memory_data_service.dart'; void main() { - bootstrap(AppComponent, const [ - const Provider(Client, useClass: InMemoryDataService) - ]); + bootstrap(AppComponent, + const [const Provider(Client, useClass: InMemoryDataService)]); } // #enddocregion final /* // #docregion v1 +import 'package:http/browser_client.dart'; void main() { - bootstrap(AppComponent, const [BrowserClient]); + bootstrap(AppComponent, [ + provide(BrowserClient, useFactory: () => new BrowserClient(), deps: []) + ]); + // Simplify bootstrap provider list to [BrowserClient] + // once there is a fix for: + // https://github.com/angular/angular/issues/9673 } // #enddocregion v1 */ diff --git a/public/docs/dart/latest/tutorial/toh-pt6.jade b/public/docs/dart/latest/tutorial/toh-pt6.jade index a939923d2b..694975a368 100644 --- a/public/docs/dart/latest/tutorial/toh-pt6.jade +++ b/public/docs/dart/latest/tutorial/toh-pt6.jade @@ -5,7 +5,7 @@ block includes - var _Http = 'BrowserClient'; - var _Angular_Http = 'Dart BrowserClient' - var _httpUrl = 'https://pub.dartlang.org/packages/http' - - var _Angular_http_library = 'Dart http library' + - var _Angular_http_library = 'Dart http package' - var _HTTP_PROVIDERS = 'BrowserClient' - var _JSON_stringify = 'JSON.encode' @@ -20,22 +20,23 @@ block start-server-and-watch block http-library :marked - We'll be using the !{_Angular_Http} to communicate with a server. - This class is exported by the !{_Angular_http_library}. + We'll be using the !{_Angular_http_library}'s + `BrowserClient` class to communicate with a server. ### Pubspec updates We need to add a package dependency for the !{_Angular_http_library}. - We also need to inform the Dart Angular 2 Transformer that we will be using - `BrowserClient` (we'll defer explaining _why_ this extra configuration is - needed until the [HTTP client chapter](../guide/server-communication.html#!#http-providers)) - by means of the transformer's `resolved_identifiers` configuration parameter. - Since we will also be needing the !{_Angular_http_library} `Client` interface, we'll - add that now as well. + We also need to add a `resolved_identifiers` entry, to inform the [angular2 + transformer][ng2x] that we'll be using `BrowserClient`. (For an explanation of why + this extra configuration is needed, see the [HTTP client chapter][guide-http].) We'll + also need to use `Client` from http, so let's add that now as well. Update `pubspec.yaml` to look like this (additions are highlighted): + [guide-http]: ../guide/server-communication.html#!#http-providers + [ng2x]: https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer + - var stylePattern = { pnk: /(http.*|resolved_identifiers:|Browser.*|Client.*)/gm }; +makeExcerpt('pubspec.yaml', 'additions', null, stylePattern) @@ -48,7 +49,7 @@ block backend We want to replace `BrowserClient`, the service that talks to the remote server, with the in-memory web API service. Our in-memory web API service, shown below, is implemented using the - standard `http` library `MockClient` class. + `http` library `MockClient` class. All `http` client implementations share a common `Client` interface, so we'll have our app use the `Client` type so that we can freely switch between implementations. @@ -58,9 +59,9 @@ block dont-be-distracted-by-backend-subst block get-heroes-details :marked - We make an asynchronous call to `http.get()` which returns an HTTP - `Response`. The response payload (`body`) is decoded as JSON via the - `_extractData` helper method. + To get the list of heroes, we first make an asynchronous call to + `http.get()`. Then we use the `_extractData` helper method to decode the + response payload (`body`). block hero-detail-comp-extra-imports-and-vars //- N/A @@ -70,7 +71,8 @@ block hero-detail-comp-updates ### Edit in the *HeroDetailComponent* We already have `HeroDetailComponent` for viewing details about a specific hero. - Supporting edit functionality is natural extensions of the detail view, so we are able to reuse `HeroDetailComponent` with a few tweaks. + Supporting edit functionality is a natural extension of the detail view, + so we are able to reuse `HeroDetailComponent` with a few tweaks. block hero-detail-comp-save-and-goback //- N/A