From fa99a8b0b2673f04de7930014944c6085f535fba Mon Sep 17 00:00:00 2001 From: Ward Bell Date: Thu, 3 Nov 2016 10:25:01 -0700 Subject: [PATCH] docs(toh-5): dashboard uses [routerLink] bindings #998 (#2718) * docs(toh-5): dashboard uses [routerLink] bindings #998 closes #998 * chore: temp add toh-5 to bad-code-excerpt-skip-patterns.txt --- .../toh-5/dart/lib/dashboard_component.1.html | 9 +++ .../toh-5/dart/lib/dashboard_component.css | 17 ++-- .../toh-5/dart/lib/dashboard_component.dart | 19 +---- .../toh-5/dart/lib/dashboard_component.html | 6 +- .../toh-5/dart/lib/dashboard_component_2.dart | 26 ------ public/docs/_examples/toh-5/e2e-spec.ts | 12 +-- .../toh-5/ts/app/dashboard.component.1.html | 9 +++ .../toh-5/ts/app/dashboard.component.2.ts | 27 ------- .../toh-5/ts/app/dashboard.component.css | 59 +++++++------- .../toh-5/ts/app/dashboard.component.html | 4 +- .../toh-5/ts/app/dashboard.component.ts | 23 ++---- .../toh-5/ts/app/heroes.component.ts | 2 + .../toh-6/dart/lib/dashboard_component.css | 59 +++++++------- .../toh-6/dart/lib/dashboard_component.dart | 11 +-- .../toh-6/dart/lib/dashboard_component.html | 4 +- public/docs/_examples/toh-6/e2e-spec.ts | 12 +-- .../toh-6/ts/app/dashboard.component.css | 61 +++++++------- .../toh-6/ts/app/dashboard.component.html | 4 +- .../toh-6/ts/app/dashboard.component.ts | 11 +-- public/docs/ts/latest/tutorial/toh-pt5.jade | 81 +++++++++---------- .../config/bad-code-excerpt-skip-patterns.txt | 1 + 21 files changed, 189 insertions(+), 268 deletions(-) create mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component.1.html delete mode 100644 public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.1.html delete mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.1.html b/public/docs/_examples/toh-5/dart/lib/dashboard_component.1.html new file mode 100644 index 0000000000..0c556b8de0 --- /dev/null +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.1.html @@ -0,0 +1,9 @@ + +

Top Heroes

+
+
+
+

{{hero.name}}

+
+
+
diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.css b/public/docs/_examples/toh-5/dart/lib/dashboard_component.css index f6263074f0..d850f074b5 100644 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.css +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.css @@ -1,6 +1,12 @@ /* #docregion */ [class*='col-'] { float: left; + text-decoration: none; + padding-right: 20px; + padding-bottom: 20px; +} +[class*='col-']:last-of-type { + padding-right: 0; } *, *:after, *:before { -webkit-box-sizing: border-box; @@ -10,12 +16,8 @@ h3 { text-align: center; margin-bottom: 0; } -[class*='col-'] { - padding-right: 20px; - padding-bottom: 20px; -} -[class*='col-']:last-of-type { - padding-right: 0; +h4 { + position: relative; } .grid { margin: 0; @@ -32,9 +34,6 @@ h3 { background-color: #607D8B; border-radius: 2px; } -h4 { - position: relative; -} .module:hover { background-color: #EEE; cursor: pointer; diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart index 8b2f6fe4af..bc2293cec1 100644 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.dart @@ -1,14 +1,13 @@ // #docplaster // #docregion +// #docregion imports 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'; +// #enddocregion imports @Component( selector: 'my-dashboard', @@ -24,24 +23,14 @@ class DashboardComponent implements OnInit { List heroes; // #docregion ctor - final Router _router; final HeroService _heroService; - DashboardComponent(this._heroService, this._router); + DashboardComponent(this._heroService); // #enddocregion ctor Future ngOnInit() async { heroes = (await _heroService.getHeroes()).skip(1).take(4).toList(); } - - // #docregion gotoDetail - void gotoDetail(Hero hero) { - var link = [ - 'HeroDetail', - {'id': hero.id.toString()} - ]; - _router.navigate(link); - } -// #enddocregion gotoDetail } +// #enddocregion component diff --git a/public/docs/_examples/toh-5/dart/lib/dashboard_component.html b/public/docs/_examples/toh-5/dart/lib/dashboard_component.html index 7133c10ada..49e77c460c 100644 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component.html +++ b/public/docs/_examples/toh-5/dart/lib/dashboard_component.html @@ -2,10 +2,10 @@

Top Heroes

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 deleted file mode 100644 index c5304f572a..0000000000 --- a/public/docs/_examples/toh-5/dart/lib/dashboard_component_2.dart +++ /dev/null @@ -1,26 +0,0 @@ -// #docplaster -// #docregion imports -import 'dart:async'; - -import 'package:angular2/core.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); - - Future ngOnInit() async { - heroes = (await _heroService.getHeroes()).skip(1).take(4).toList(); - } - - gotoDetail(Hero hero) {/* not implemented yet */} -} diff --git a/public/docs/_examples/toh-5/e2e-spec.ts b/public/docs/_examples/toh-5/e2e-spec.ts index 1bb398b7f7..9da4fc7765 100644 --- a/public/docs/_examples/toh-5/e2e-spec.ts +++ b/public/docs/_examples/toh-5/e2e-spec.ts @@ -1,4 +1,4 @@ -'use strict'; // necessary for es6 output in node +'use strict'; // necessary for es6 output in node import { browser, element, by, ElementFinder } from 'protractor'; import { promise } from 'selenium-webdriver'; @@ -42,16 +42,16 @@ describe('Tutorial part 5', () => { beforeAll(() => browser.get('')); function getPageElts() { - let hrefElts = element.all(by.css('my-app a')); + let navElts = element.all(by.css('my-app nav a')); return { - hrefs: hrefElts, + navElts: navElts, - myDashboardHref: hrefElts.get(0), + myDashboardHref: navElts.get(0), myDashboard: element(by.css('my-app my-dashboard')), topHeroes: element.all(by.css('my-app my-dashboard > div h4')), - myHeroesHref: hrefElts.get(1), + myHeroesHref: navElts.get(1), myHeroes: element(by.css('my-app my-heroes')), allHeroes: element.all(by.css('my-app my-heroes li')), selectedHero: element(by.css('my-app li.selected')), @@ -73,7 +73,7 @@ describe('Tutorial part 5', () => { const expectedViewNames = ['Dashboard', 'Heroes']; it(`has views ${expectedViewNames}`, () => { - let viewNames = getPageElts().hrefs.map((el: ElementFinder) => el.getText()); + let viewNames = getPageElts().navElts.map((el: ElementFinder) => el.getText()); expect(viewNames).toEqual(expectedViewNames); }); diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.1.html b/public/docs/_examples/toh-5/ts/app/dashboard.component.1.html new file mode 100644 index 0000000000..0c556b8de0 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.1.html @@ -0,0 +1,9 @@ + +

Top Heroes

+
+
+
+

{{hero.name}}

+
+
+
diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts deleted file mode 100644 index 4e0e8553bc..0000000000 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts +++ /dev/null @@ -1,27 +0,0 @@ -// #docplaster -// #docregion imports -import { Component, OnInit } from '@angular/core'; - -import { Hero } from './hero'; -import { HeroService } from './hero.service'; -// #enddocregion imports - -@Component({ - moduleId: module.id, - selector: 'my-dashboard', - templateUrl: 'dashboard.component.html' -}) -// #docregion component -export class DashboardComponent implements OnInit { - - heroes: Hero[] = []; - - constructor(private heroService: HeroService) { } - - ngOnInit(): void { - this.heroService.getHeroes() - .then(heroes => this.heroes = heroes.slice(1, 5)); - } - - gotoDetail(hero: Hero): void { /* not implemented yet */} -} diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.css b/public/docs/_examples/toh-5/ts/app/dashboard.component.css index f6263074f0..dc7fb7ce06 100644 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.css +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.css @@ -1,22 +1,26 @@ /* #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; } +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +h4 { + position: relative; +} .grid { margin: 0; } @@ -24,16 +28,13 @@ h3 { 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; + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; } .module:hover { background-color: #EEE; @@ -47,15 +48,15 @@ h4 { padding-right: 20px; } @media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } + .module { + font-size: 10px; + max-height: 75px; } } @media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } + .grid { + margin: 0; + } + .module { + min-width: 60px; + } } diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.html b/public/docs/_examples/toh-5/ts/app/dashboard.component.html index 67ac6aa459..49e77c460c 100644 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.html +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.html @@ -2,10 +2,10 @@

Top Heroes

diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts index f72a149c8c..cb5cfc5b82 100644 --- a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts @@ -1,13 +1,13 @@ // #docplaster // #docregion +// #docregion imports import { Component, OnInit } from '@angular/core'; -// #docregion import-router -import { Router } from '@angular/router'; -// #enddocregion import-router import { Hero } from './hero'; import { HeroService } from './hero.service'; - // #docregion metadata +// #enddocregion imports + +// #docregion metadata @Component({ moduleId: module.id, selector: 'my-dashboard', @@ -19,27 +19,18 @@ import { HeroService } from './hero.service'; // #docregion metadata }) // #enddocregion metadata -// #docregion component +// #docregion class export class DashboardComponent implements OnInit { heroes: Hero[] = []; // #docregion ctor - constructor( - private router: Router, - private heroService: HeroService) { - } + constructor(private heroService: HeroService) { } // #enddocregion ctor ngOnInit(): void { this.heroService.getHeroes() .then(heroes => this.heroes = heroes.slice(1, 5)); } - - // #docregion gotoDetail - gotoDetail(hero: Hero): void { - let link = ['/detail', hero.id]; - this.router.navigate(link); - } - // #enddocregion gotoDetail } +// #enddocregion class diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/app/heroes.component.ts index cbcb598ac2..1f2290c853 100644 --- a/public/docs/_examples/toh-5/ts/app/heroes.component.ts +++ b/public/docs/_examples/toh-5/ts/app/heroes.component.ts @@ -40,8 +40,10 @@ export class HeroesComponent implements OnInit { this.selectedHero = hero; } + // #docregion gotoDetail gotoDetail(): void { this.router.navigate(['/detail', this.selectedHero.id]); } + // #enddocregion gotoDetail // #docregion renaming } diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.css b/public/docs/_examples/toh-6/dart/lib/dashboard_component.css index f6263074f0..dc7fb7ce06 100644 --- a/public/docs/_examples/toh-6/dart/lib/dashboard_component.css +++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.css @@ -1,22 +1,26 @@ /* #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; } +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +h4 { + position: relative; +} .grid { margin: 0; } @@ -24,16 +28,13 @@ h3 { 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; + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; } .module:hover { background-color: #EEE; @@ -47,15 +48,15 @@ h4 { padding-right: 20px; } @media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } + .module { + font-size: 10px; + max-height: 75px; } } @media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } + .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 index d23b7f543d..ac71e10e17 100644 --- a/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart +++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.dart @@ -18,20 +18,11 @@ import 'hero_search_component.dart'; class DashboardComponent implements OnInit { List heroes; - final Router _router; final HeroService _heroService; - DashboardComponent(this._heroService, this._router); + DashboardComponent(this._heroService); Future ngOnInit() async { heroes = (await _heroService.getHeroes()).skip(1).take(4).toList(); } - - void gotoDetail(Hero hero) { - var link = [ - 'HeroDetail', - {'id': hero.id.toString()} - ]; - _router.navigate(link); - } } diff --git a/public/docs/_examples/toh-6/dart/lib/dashboard_component.html b/public/docs/_examples/toh-6/dart/lib/dashboard_component.html index fe1ee585f6..db8546ccd2 100644 --- a/public/docs/_examples/toh-6/dart/lib/dashboard_component.html +++ b/public/docs/_examples/toh-6/dart/lib/dashboard_component.html @@ -1,10 +1,10 @@

Top Heroes

diff --git a/public/docs/_examples/toh-6/e2e-spec.ts b/public/docs/_examples/toh-6/e2e-spec.ts index 814fa2004c..c4a68aec52 100644 --- a/public/docs/_examples/toh-6/e2e-spec.ts +++ b/public/docs/_examples/toh-6/e2e-spec.ts @@ -1,4 +1,4 @@ -'use strict'; // necessary for es6 output in node +'use strict'; // necessary for es6 output in node import { browser, element, by, ElementFinder, ElementArrayFinder } from 'protractor'; import { promise } from 'selenium-webdriver'; @@ -48,16 +48,16 @@ describe('Tutorial part 6', () => { beforeAll(() => browser.get('')); function getPageElts() { - let hrefElts = element.all(by.css('my-app a')); + let navElts = element.all(by.css('my-app nav a')); return { - hrefs: hrefElts, + navElts: navElts, - myDashboardHref: hrefElts.get(0), + myDashboardHref: navElts.get(0), myDashboard: element(by.css('my-app my-dashboard')), topHeroes: element.all(by.css('my-app my-dashboard > div h4')), - myHeroesHref: hrefElts.get(1), + myHeroesHref: navElts.get(1), myHeroes: element(by.css('my-app my-heroes')), allHeroes: element.all(by.css('my-app my-heroes li')), selectedHero: element(by.css('my-app li.selected')), @@ -82,7 +82,7 @@ describe('Tutorial part 6', () => { const expectedViewNames = ['Dashboard', 'Heroes']; it(`has views ${expectedViewNames}`, () => { - let viewNames = getPageElts().hrefs.map((el: ElementFinder) => el.getText()); + let viewNames = getPageElts().navElts.map((el: ElementFinder) => el.getText()); expect(viewNames).toEqual(expectedViewNames); }); diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.css b/public/docs/_examples/toh-6/ts/app/dashboard.component.css index ce6e963a5f..dc7fb7ce06 100644 --- a/public/docs/_examples/toh-6/ts/app/dashboard.component.css +++ b/public/docs/_examples/toh-6/ts/app/dashboard.component.css @@ -1,23 +1,26 @@ -/* #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; } +a { + text-decoration: none; +} +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +h3 { + text-align: center; margin-bottom: 0; +} +h4 { + position: relative; +} .grid { margin: 0; } @@ -25,16 +28,13 @@ h3 { 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; + padding: 20px; + text-align: center; + color: #eee; + max-height: 120px; + min-width: 120px; + background-color: #607D8B; + border-radius: 2px; } .module:hover { background-color: #EEE; @@ -48,16 +48,15 @@ h4 { padding-right: 20px; } @media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } + .module { + font-size: 10px; + max-height: 75px; } } @media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; - } + .grid { + margin: 0; + } + .module { + min-width: 60px; + } } -/* #enddocregion */ diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.html b/public/docs/_examples/toh-6/ts/app/dashboard.component.html index fe1ee585f6..db8546ccd2 100644 --- a/public/docs/_examples/toh-6/ts/app/dashboard.component.html +++ b/public/docs/_examples/toh-6/ts/app/dashboard.component.html @@ -1,10 +1,10 @@

Top Heroes

diff --git a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts index 92df6569b1..a66ec3b89b 100644 --- a/public/docs/_examples/toh-6/ts/app/dashboard.component.ts +++ b/public/docs/_examples/toh-6/ts/app/dashboard.component.ts @@ -1,6 +1,5 @@ // #docregion , search import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; import { Hero } from './hero'; import { HeroService } from './hero.service'; @@ -15,18 +14,10 @@ import { HeroService } from './hero.service'; export class DashboardComponent implements OnInit { heroes: Hero[] = []; - constructor( - private router: Router, - private heroService: HeroService) { - } + constructor(private heroService: HeroService) { } ngOnInit(): void { this.heroService.getHeroes() .then(heroes => this.heroes = heroes.slice(1, 5)); } - - gotoDetail(hero: Hero): void { - let link = ['/detail', hero.id]; - this.router.navigate(link); - } } diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade index 9f97f4f088..79d643eaa9 100644 --- a/public/docs/ts/latest/tutorial/toh-pt5.jade +++ b/public/docs/ts/latest/tutorial/toh-pt5.jade @@ -370,16 +370,12 @@ block redirect-vs-use-as-default :marked Create that file with this content: -+makeExcerpt('app/dashboard.component.html') ++makeExample('app/dashboard.component.1.html', '', 'app/dashboard.component.html') :marked We use `*ngFor` once again to iterate over a list of heroes and display their names. We added extra `
` elements to help with styling later in this chapter. - There's a `(click)` binding to a `gotoDetail` method we haven't written yet and - we're displaying a list of heroes that we don't have. - We have work to do, starting with those heroes. - ### Share the *HeroService* We'd like to re-use the `HeroService` to populate the component's `heroes` !{_array}. @@ -394,12 +390,12 @@ block redirect-vs-use-as-default Open dashboard.component.ts and add the requisite `import` statements. -+makeExcerpt('app/dashboard.component.2.ts','imports') ++makeExcerpt('app/dashboard.component.ts','imports') :marked Now implement the `DashboardComponent` class like this: -+makeExcerpt('app/dashboard.component.2.ts (class)', 'component') ++makeExcerpt('app/dashboard.component.ts (class)', 'class') :marked We've seen this kind of logic before in the `HeroesComponent`: @@ -408,8 +404,7 @@ block redirect-vs-use-as-default * Inject the `HeroService` in the constructor and hold it in a private `!{_priv}heroService` field. * Call the service to get heroes inside the Angular `ngOnInit` lifecycle hook. - The noteworthy differences: we cherry-pick four heroes (2nd, 3rd, 4th, and 5th) - and stub the `gotoDetail` method until we're ready to implement it. + In this dashboard we cherry-pick four heroes (2nd, 3rd, 4th, and 5th) with the `Array.slice` method. Refresh the browser and see four heroes in the new dashboard. @@ -580,7 +575,7 @@ block extract-id incremental improvement and migrate the template to its own file, called hero-detail.component.html: -+makeExample('app/hero-detail.component.html') ++makeExample('app/hero-detail.component.html')(format='.') :marked We update the component metadata with a `moduleId` and a `templateUrl` pointing to the template file that we just created. @@ -596,32 +591,26 @@ block extract-id When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero. - In the dashboard template we bound each hero's click event to the `gotoDetail` method, passing along the selected `hero` entity. + Although the dashboard heroes are presented as button-like blocks, they should behave like anchor tags. + When hovering over a hero block, the target URL should display in the browser status bar + and the user should be able to copy the link or open the hero detail view in a new tab. -+makeExcerpt('app/dashboard.component.html', 'click') + To achieve this effect, reopen the `dashboard.component.html` and replace the repeated `
` tags + with `` tags. The opening `` tag looks like this: -:marked - We stubbed the `gotoDetail` method when we rewrote the `DashboardComponent`. - Now we give it a real implementation. - -+makeExcerpt('app/dashboard.component.ts','gotoDetail') ++makeExample('app/dashboard.component.html', 'click', 'app/dashboard.component.html (repeated tag)') - var _pathVsName = _docsFor == 'dart' ? 'name' : 'path' :marked - The `gotoDetail` method navigates in two steps: + Notice the `[routerLink]` binding. - 1. Set a route *link parameters !{_array}* - 1. Pass the !{_array} to the router's navigate method + In the top level navigation in the [`AppComponent` + template](#router-links) has router links set to fixed !{_pathVsName}s of the + destination routes, "/dashboard" and "/heroes". - For navigation, we wrote router links as *link - parameters !{_array}s* in the [`AppComponent` - template](#router-links). Those link parameters - !{_array}s had only one element, the !{_pathVsName} of the - destination route. - - This link parameters !{_array} has two elements, the ***!{_pathVsName}*** of - the destination route and a ***route parameter*** with - an `id` field set to the value of the selected hero's `id`. + This time, we're binding to an expression containing a **link parameters !{_array}**. + The !{_array} has two elements, the ***!{_pathVsName}*** of + the destination route and a ***route parameter*** set to the value of the current hero's `id`. The two !{_array} items align with the ***!{_pathVsName}*** and ***:id*** token in the parameterized hero detail route definition we added to @@ -630,14 +619,6 @@ block extract-id - var _file = _docsFor == 'dart' ? 'app/app.component.ts' : 'app/app.module.3.ts' +makeExcerpt(_file + ' (hero detail)', 'hero-detail') -:marked - The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way: - import the `router` reference and inject it in the constructor (along with the `HeroService`): - -+makeExcerpt('app/dashboard.component.ts ()','import-router', '') - -+makeExcerpt('app/dashboard.component.ts', 'ctor', '') - :marked Refresh the browser and select a hero from the dashboard; the app should navigate directly to that hero’s details. @@ -703,14 +684,14 @@ block extract-id :marked Our goal is to move the detail to its own view and navigate to it when the user decides to edit a selected hero. - Delete the `

` at the top (forgot about it during the `AppComponent`-to-`HeroesComponent` conversion). + Delete the `

` at the top (we forgot about it during the `AppComponent`-to-`HeroesComponent` conversion). Delete the last line of the template with the `` tags. We'll no longer show the full `HeroDetailComponent` here. We're going to display the hero detail on its own page and route to it as we did in the dashboard. - But we'll throw in a small twist for variety. + We'll throw in a small twist for variety. We are keeping the "master/detail" style but shrinking the detail to a "mini", read-only version. When the user selects a hero from the list, we *don't* go to the detail page. We show a *mini-detail* on *this* page instead and make the user click a button to navigate to the *full detail *page. @@ -770,15 +751,25 @@ block heroes-component-cleanup +makeExcerpt('app/heroes.component.ts (revised metadata)', 'metadata') :marked - Now we can see what's going on as we update the component class along the same lines as the dashboard: + ### Update the _HeroesComponent_ class. - 1. Import the `router` + The `HeroesComponent` navigates to the `HeroesDetailComponent` in response to a button click. + The button's _click_ event is bound to a `gotoDetail` method that navigates _imperatively_ + by telling the router where to go. + + This approach requires some changes to the component class: + + 1. Import the `router` from the Angular router library 1. Inject the `router` in the constructor (along with the `HeroService`) - 1. Implement the `gotoDetail` method by calling the `router.navigate` method + 1. Implement `gotoDetail` by calling the `router.navigate` method - with a two-part hero-detail link parameters !{_array}. - - Here's the revised component class: ++makeExcerpt('app/heroes.component.ts', 'gotoDetail') +:marked + Note that we're passing a two-element **link parameters !{_array}** + — a path and the route parameter — to + the `router.navigate` method just as we did in the `[routerLink]` binding + back in the `DashboardComponent` + Here's the fully revised `HeroesComponent` class: +makeExcerpt('app/heroes.component.ts', 'class') diff --git a/scripts/config/bad-code-excerpt-skip-patterns.txt b/scripts/config/bad-code-excerpt-skip-patterns.txt index b66e9ce758..731cbff933 100644 --- a/scripts/config/bad-code-excerpt-skip-patterns.txt +++ b/scripts/config/bad-code-excerpt-skip-patterns.txt @@ -5,3 +5,4 @@ /ts/latest/guide/style-guide.html # https://github.com/angular/angular.io/issues/2123 /ts/latest/guide/upgrade.html # In a transient state until RC6 - @filipe.silva /[jt]s/.*/api/forms/index/NG_VALIDATORS-let.html # RC6 contains broken example tags +/dart/latest/tutorial/toh-pt5.html