From 1365d8252786459c846fdaaa31c5d5c8e1958c6e Mon Sep 17 00:00:00 2001 From: John Papa Date: Wed, 23 Dec 2015 09:42:57 -0800 Subject: [PATCH] docs(tutorial): add part 5-routing --- .../_examples/toh-2/ts/app/app.component.ts | 6 +- .../_examples/toh-3/ts/app/app.component.ts | 6 +- .../toh-3/ts/app/hero-detail.component.ts | 2 +- .../_examples/toh-4/ts/app/app.component.1.ts | 7 +- .../_examples/toh-4/ts/app/app.component.ts | 8 +- .../toh-4/ts/app/hero-detail.component.ts | 9 +- public/docs/_examples/toh-5/e2e-spec.js | 111 +++ .../ts-snippets/app/app.component.pt4.ts | 111 --- .../toh-5/ts-snippets/app/hero.service.pt4.ts | 8 - .../toh-5/ts-snippets/app/index.pt4.html | 186 ----- .../toh-5/ts-snippets/app/main.pt4.ts | 13 - .../toh-5/ts-snippets/app/route.config.pt4.ts | 50 -- .../_examples/toh-5/ts/app/app.component.1.js | 54 ++ .../_examples/toh-5/ts/app/app.component.1.ts | 30 + .../_examples/toh-5/ts/app/app.component.2.js | 61 ++ .../_examples/toh-5/ts/app/app.component.2.ts | 40 + .../_examples/toh-5/ts/app/app.component.css | 31 + .../_examples/toh-5/ts/app/app.component.js | 85 +++ .../_examples/toh-5/ts/app/app.component.ts | 59 ++ .../toh-5/ts/app/dashboard.component.1.js | 35 + .../toh-5/ts/app/dashboard.component.1.ts | 8 + .../toh-5/ts/app/dashboard.component.2.js | 48 ++ .../toh-5/ts/app/dashboard.component.2.ts | 27 + .../toh-5/ts/app/dashboard.component.css | 63 ++ .../toh-5/ts/app/dashboard.component.html | 11 + .../toh-5/ts/app/dashboard.component.js | 59 ++ .../toh-5/ts/app/dashboard.component.ts | 42 ++ .../toh-5/ts/app/hero-detail.component.css | 25 + .../toh-5/ts/app/hero-detail.component.html | 14 + .../toh-5/ts/app/hero-detail.component.js | 68 ++ .../toh-5/ts/app/hero-detail.component.ts | 57 ++ public/docs/_examples/toh-5/ts/app/hero.js | 8 + .../_examples/toh-5/ts/app/hero.service.js | 51 ++ .../_examples/toh-5/ts/app/hero.service.ts | 28 + public/docs/_examples/toh-5/ts/app/hero.ts | 4 + .../toh-5/ts/app/heroes.component.css | 47 ++ .../toh-5/ts/app/heroes.component.html | 21 + .../toh-5/ts/app/heroes.component.js | 65 ++ .../toh-5/ts/app/heroes.component.ts | 50 ++ public/docs/_examples/toh-5/ts/app/main.js | 16 + public/docs/_examples/toh-5/ts/app/main.ts | 4 + .../_examples/toh-5/ts/app/mock-heroes.js | 22 + .../_examples/toh-5/ts/app/mock-heroes.ts | 16 + public/docs/_examples/toh-5/ts/index.html | 38 + public/docs/_examples/toh-5/ts/plnkr.json | 9 + public/docs/_examples/toh-5/ts/styles.css | 7 + .../tutorial/ts/app/dashboard.component.ts | 3 +- .../tutorial/ts/app/hero-detail.component.ts | 7 +- .../_examples/tutorial/ts/app/hero.service.ts | 15 +- public/docs/ts/latest/guide/router.jade | 8 +- .../ts/latest/guide/server-communication.jade | 3 +- public/docs/ts/latest/tutorial/_data.json | 4 + public/docs/ts/latest/tutorial/toh-pt4.jade | 2 +- public/docs/ts/latest/tutorial/toh-pt5.jade | 686 ++++++++++++++++++ .../plunker-separate-window-button.png | Bin 0 -> 7118 bytes .../devguide/toh/dashboard-top-heroes.png | Bin 17689 -> 23510 bytes .../images/devguide/toh/mini-hero-detail.png | Bin 0 -> 9896 bytes 57 files changed, 2049 insertions(+), 399 deletions(-) create mode 100644 public/docs/_examples/toh-5/e2e-spec.js delete mode 100644 public/docs/_examples/toh-5/ts-snippets/app/app.component.pt4.ts delete mode 100644 public/docs/_examples/toh-5/ts-snippets/app/hero.service.pt4.ts delete mode 100644 public/docs/_examples/toh-5/ts-snippets/app/index.pt4.html delete mode 100644 public/docs/_examples/toh-5/ts-snippets/app/main.pt4.ts delete mode 100644 public/docs/_examples/toh-5/ts-snippets/app/route.config.pt4.ts create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.1.js create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.1.ts create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.2.js create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.2.ts create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.css create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.js create mode 100644 public/docs/_examples/toh-5/ts/app/app.component.ts create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.1.js create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.2.js create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.css create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.html create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.js create mode 100644 public/docs/_examples/toh-5/ts/app/dashboard.component.ts create mode 100644 public/docs/_examples/toh-5/ts/app/hero-detail.component.css create mode 100644 public/docs/_examples/toh-5/ts/app/hero-detail.component.html create mode 100644 public/docs/_examples/toh-5/ts/app/hero-detail.component.js create mode 100644 public/docs/_examples/toh-5/ts/app/hero-detail.component.ts create mode 100644 public/docs/_examples/toh-5/ts/app/hero.js create mode 100644 public/docs/_examples/toh-5/ts/app/hero.service.js create mode 100644 public/docs/_examples/toh-5/ts/app/hero.service.ts create mode 100644 public/docs/_examples/toh-5/ts/app/hero.ts create mode 100644 public/docs/_examples/toh-5/ts/app/heroes.component.css create mode 100644 public/docs/_examples/toh-5/ts/app/heroes.component.html create mode 100644 public/docs/_examples/toh-5/ts/app/heroes.component.js create mode 100644 public/docs/_examples/toh-5/ts/app/heroes.component.ts create mode 100644 public/docs/_examples/toh-5/ts/app/main.js create mode 100644 public/docs/_examples/toh-5/ts/app/main.ts create mode 100644 public/docs/_examples/toh-5/ts/app/mock-heroes.js create mode 100644 public/docs/_examples/toh-5/ts/app/mock-heroes.ts create mode 100644 public/docs/_examples/toh-5/ts/index.html create mode 100644 public/docs/_examples/toh-5/ts/plnkr.json create mode 100644 public/docs/_examples/toh-5/ts/styles.css create mode 100644 public/docs/ts/latest/tutorial/toh-pt5.jade create mode 100644 public/resources/images/devguide/plunker-separate-window-button.png create mode 100644 public/resources/images/devguide/toh/mini-hero-detail.png diff --git a/public/docs/_examples/toh-2/ts/app/app.component.ts b/public/docs/_examples/toh-2/ts/app/app.component.ts index 3cb0c3f5ed..f583eca8e7 100644 --- a/public/docs/_examples/toh-2/ts/app/app.component.ts +++ b/public/docs/_examples/toh-2/ts/app/app.component.ts @@ -79,10 +79,10 @@ interface Hero { // #enddocregion styles-1 }) export class AppComponent { - public title = 'Tour of Heroes'; - public heroes = HEROES; + title = 'Tour of Heroes'; + heroes = HEROES; // #docregion selected-hero-1 - public selectedHero: Hero; + selectedHero: Hero; // #enddocregion selected-hero-1 // #docregion on-select-1 diff --git a/public/docs/_examples/toh-3/ts/app/app.component.ts b/public/docs/_examples/toh-3/ts/app/app.component.ts index c99b7faaf2..2a5c79abd5 100644 --- a/public/docs/_examples/toh-3/ts/app/app.component.ts +++ b/public/docs/_examples/toh-3/ts/app/app.component.ts @@ -76,9 +76,9 @@ import {HeroDetailComponent} from './hero-detail.component'; // #enddocregion directives }) export class AppComponent { - public title = 'Tour of Heroes'; - public heroes = HEROES; - public selectedHero: Hero; + title = 'Tour of Heroes'; + heroes = HEROES; + selectedHero: Hero; onSelect(hero: Hero) { this.selectedHero = hero; } } diff --git a/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts index 16ad8d80b8..90b47c0996 100644 --- a/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts +++ b/public/docs/_examples/toh-3/ts/app/hero-detail.component.ts @@ -31,7 +31,7 @@ import {Hero} from './hero'; export class HeroDetailComponent { // #enddocregion v1 // #docregion hero - public hero: Hero; + hero: Hero; // #enddocregion hero // #docregion v1 } diff --git a/public/docs/_examples/toh-4/ts/app/app.component.1.ts b/public/docs/_examples/toh-4/ts/app/app.component.1.ts index 88cd0c400d..20ec0babc5 100644 --- a/public/docs/_examples/toh-4/ts/app/app.component.1.ts +++ b/public/docs/_examples/toh-4/ts/app/app.component.1.ts @@ -27,11 +27,11 @@ import {HeroService} from './hero.service.1'; // #docregion on-init export class AppComponent implements OnInit { // #enddocregion on-init - public title = 'Tour of Heroes'; + title = 'Tour of Heroes'; // #docregion heroes-prop - public heroes: Hero[]; + heroes: Hero[]; // #enddocregion heroes-prop - public selectedHero: Hero; + selectedHero: Hero; // #docregion new-service heroService = new HeroService(); // don't do this @@ -61,3 +61,4 @@ export class AppComponent implements OnInit { // #docregion on-init } // #enddocregion on-init +// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-4/ts/app/app.component.ts b/public/docs/_examples/toh-4/ts/app/app.component.ts index e8e99ae19d..76035bb3d7 100644 --- a/public/docs/_examples/toh-4/ts/app/app.component.ts +++ b/public/docs/_examples/toh-4/ts/app/app.component.ts @@ -9,6 +9,7 @@ import {HeroService} from './hero.service'; @Component({ selector: 'my-app', + // #docregion template template:`

{{title}}

My Heroes

@@ -21,6 +22,7 @@ import {HeroService} from './hero.service'; `, + // #enddocregion template styles:[` .selected { background-color: #CFD8DC !important; @@ -73,9 +75,9 @@ import {HeroService} from './hero.service'; providers: [HeroService] }) export class AppComponent implements OnInit { - public title = 'Tour of Heroes'; - public heroes: Hero[]; - public selectedHero: Hero; + title = 'Tour of Heroes'; + heroes: Hero[]; + selectedHero: Hero; constructor(private _heroService: HeroService) { } diff --git a/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts index 30b8184442..72024f533a 100644 --- a/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts +++ b/public/docs/_examples/toh-4/ts/app/hero-detail.component.ts @@ -1,3 +1,4 @@ +// #docregion import {Component} from 'angular2/core'; import {Hero} from './hero'; @@ -5,8 +6,10 @@ import {Hero} from './hero'; selector: 'my-hero-detail', template: `
-

{{hero.name}} details!

-
{{hero.id}}
+

{{hero.name}} details

+
+ {{hero.id}} +
@@ -16,5 +19,5 @@ import {Hero} from './hero'; inputs: ['hero'] }) export class HeroDetailComponent { - public hero: Hero; + hero: Hero; } diff --git a/public/docs/_examples/toh-5/e2e-spec.js b/public/docs/_examples/toh-5/e2e-spec.js new file mode 100644 index 0000000000..f35fcd1287 --- /dev/null +++ b/public/docs/_examples/toh-5/e2e-spec.js @@ -0,0 +1,111 @@ +describe('Tutorial', function () { + + beforeAll(function () { + browser.get(''); + }); + + + function getPageStruct() { + hrefEles = element.all(by.css('my-app a')); + + return { + hrefs: hrefEles, + myDashboardHref: hrefEles.get(0), + myDashboardParent: element(by.css('my-app my-dashboard')), + topHeroes: element.all(by.css('my-app my-dashboard .module.hero')), + + myHeroesHref: hrefEles.get(1), + myHeroesParent: element(by.css('my-app my-heroes')), + allHeroes: element.all(by.css('my-app my-heroes li')), + + heroDetail: element(by.css('my-app my-hero-detail')) + } + } + + it('should be able to see the start screen', function () { + var page = getPageStruct(); + expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices'); + expect(page.myDashboardHref.getText()).toEqual("Dashboard"); + expect(page.myHeroesHref.getText()).toEqual("Heroes"); + }); + + it('should be able to see dashboard choices', function () { + var page = getPageStruct(); + expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices"); + }); + + it('should be able to toggle the views', function () { + var page = getPageStruct(); + + expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes'); + page.myHeroesHref.click().then(function() { + expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element'); + expect(page.allHeroes.count()).toBeGreaterThan(4, "should be more than 4 heroes shown"); + return page.myDashboardHref.click(); + }).then(function() { + expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element'); + }); + + }); + + it('should be able to edit details from "Dashboard" view', function () { + var page = getPageStruct(); + expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available'); + var heroEle = page.topHeroes.get(3); + var heroDescrEle = heroEle.element(by.css('h4')); + var heroDescr; + return heroDescrEle.getText().then(function(text) { + heroDescr = text; + return heroEle.click(); + }).then(function() { + return editDetails(page, heroDescr, '-foo'); + }).then(function() { + expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be back'); + expect(heroDescrEle.getText()).toEqual(heroDescr + '-foo'); + }); + }); + + it('should be able to edit details from "Heroes" view', function () { + var page = getPageStruct(); + expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present'); + var viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details')); + var heroEle, heroDescr; + page.myHeroesHref.click().then(function() { + expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); + expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present'); + expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should not yet be present'); + heroEle = page.allHeroes.get(2); + return heroEle.getText(); + }).then(function(text) { + // remove leading 'id' from the element + heroDescr = text.substr(text.indexOf(' ')+1); + return heroEle.click(); + }).then(function() { + expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible'); + return viewDetailsButtonEle.click(); + }).then(function() { + return editDetails(page, heroDescr, '-bar'); + }).then(function() { + expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be back'); + expect(heroEle.getText()).toContain(heroDescr + '-bar'); + expect(viewDetailsButtonEle.isPresent()).toBe(false, 'viewDetails button should again NOT be present'); + }); + }); + + function editDetails(page, origValue, textToAdd) { + expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present'); + expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present'); + expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details'); + var inputEle = page.heroDetail.element(by.css('input')); + expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box'); + var backButtonEle = page.heroDetail.element(by.css('button')); + expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button'); + var detailTextEle = page.heroDetail.element(by.css('div h2')); + expect(detailTextEle.getText()).toContain(origValue); + return sendKeys(inputEle, textToAdd).then(function () { + expect(detailTextEle.getText()).toContain(origValue + textToAdd); + return backButtonEle.click(); + }); + } + +}); diff --git a/public/docs/_examples/toh-5/ts-snippets/app/app.component.pt4.ts b/public/docs/_examples/toh-5/ts-snippets/app/app.component.pt4.ts deleted file mode 100644 index aed30ab470..0000000000 --- a/public/docs/_examples/toh-5/ts-snippets/app/app.component.pt4.ts +++ /dev/null @@ -1,111 +0,0 @@ -// #docregion -import {Component} from 'angular2/angular2'; - -@Component({selector: 'my-app'}) -export class AppComponent { } -// #enddocregion - -// #docregion initialize-routes-property -export class AppComponent { - public title = 'Tour of Heroes'; - public routes = Routes; -} -// #enddocregion initialize-routes-property - -// #docregion oninit -onInit() { - this.heroes = this.getHeroes(); -} - -getHeroes() { - this.heroes = []; - - this._heroService.getHeroes() - .then((heroes: Hero[]) => this.heroes = heroes); - - return this.heroes; -} -// #enddocregion oninit - -// #docregion styles -styles: [` - .router-link {padding: 5px;text-decoration: none;} - .router-link:visited, .router-link:link {color: #444;} - .router-link:hover {color: white; background-color: #1171a3; text-decoration: none;} - .router-link.router-link-active {color: white; background-color: #52b9e9; text-decoration: none;} -`], -// #enddocregion styles - -// #docregion import-params -import {RouteParams} from 'angular2/router'; -// #enddocregion import-params -// #docregion inject-routeparams -constructor(private _routeParams: RouteParams) {} -// #enddocregion inject-routeparams -// #docregion access-params -export class HeroDetailComponent implements OnInit { - -onInit() { } -// #enddocregion access-params -// #docregion import-onit -import {Component, FORM_DIRECTIVES, OnInit} from 'angular2/angular2'; -// #enddocregion import-onit -// #docregion onit-id-param -onInit() { let id = +this._routeParams.get('id'); // TODO: get the hero using it’s id } -// #enddocregion onit-id-param - -// #docregion onit-hero-id -onInit() { - if (!this.hero) { - let id = +this._routeParams.get('id'); - // TODO: get the hero using it’s id - } -} -// #docregion onit-hero-id - -// #docregion inject-hero-service -constructor( - private _heroService: HeroService, - private _routeParams: RouteParams) { -} -// #docregion inject-hero-service - -// #docregion onit-hero-method - onInit() { - if (!this.hero) { - let id = +this._routeParams.get('id'); - this._heroService.getHero(id).then((hero: Hero) => this.hero = hero); - } - } -// #docregion onit-hero-method - -// #docregion select-hero -import {Router} from 'angular2/router'; -import {Routes} from './route.config'; - -constructor(private _heroService: HeroService, private _router: Router) { } - -gotoDetail() { - this._router.navigate([`/${Routes.detail.as}`, { id: this.selectedHero.id }]); -} -// #enddocregion select-hero - -// #docregion reference-heroes-component -@Component({ - selector: 'my-heroes', - templateUrl: 'app/heroes.component.html', - styleUrls: ['app/heroes.component.css'], - directives: [FORM_DIRECTIVES, HeroDetailComponent] -}) -export class HeroesComponent { -// #docregion reference-heroes-component - -// #docregion reference-hero-detail-component -@Component({ - selector: 'my-hero-detail', - templateUrl: 'app/hero-detail.component.html', - directives: [FORM_DIRECTIVES], - inputs: ['hero'] -}) -export class HeroDetailComponent { -// #enddocregion reference-hero-detail-component \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts-snippets/app/hero.service.pt4.ts b/public/docs/_examples/toh-5/ts-snippets/app/hero.service.pt4.ts deleted file mode 100644 index a30e6632e6..0000000000 --- a/public/docs/_examples/toh-5/ts-snippets/app/hero.service.pt4.ts +++ /dev/null @@ -1,8 +0,0 @@ -// #docregion get-hero-method - getHero(id: number) { - return Promise.resolve(HEROES) - .then((heroes: Hero[]) => { return heroes.filter((h) => { - return h.id === id; - })[0]}); - } -// #docregion get-hero-method \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts-snippets/app/index.pt4.html b/public/docs/_examples/toh-5/ts-snippets/app/index.pt4.html deleted file mode 100644 index dd397ddbc8..0000000000 --- a/public/docs/_examples/toh-5/ts-snippets/app/index.pt4.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - - - -System.import('app/bootstrap'); - - -import {Component} from 'angular2/angular2'; - -@Component({ - selector: 'my-app', - template: ` -

{{title}}

- ` -}) -export class AppComponent { - public title = 'Tour of Heroes'; -} - - - - import {Component} from 'angular2/angular2'; - import {RouteConfig} from 'angular2/router'; - - import {APP_ROUTES} from './route.config'; - - - @Component({ - selector: 'my-app', - template: ` -

{{title}}

- ` - }) - @RouteConfig(APP_ROUTES) - export class AppComponent { - public title = 'Tour of Heroes'; - } - - - - template: ` -

{{title}}

- -` - - - -import {Component} from 'angular2/angular2'; - -@Component({ - selector: 'my-dashboard', - template: ` -

Dashboard Goes Here

- ` -}) -export class DashboardComponent {} - - - -template: ` -

{{title}}

- Dashboard - Heroes - -`, - - - -template: ` -

Top Heroes

-
-
-
-

{{hero.name}}

-
-
-
-` - - - -[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 10em; } -.col-1-4 { width: 25%; } -.module { - padding: 20px; text-align: center; - color: #eee; max-height: 120px; min-width: 120px; - background-color: #1171a3; -} -.module:hover { background-color: #52b9e9; cursor: pointer; } -.grid-pad { padding: 20px 0 20px 20px; } -.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; } -} - - - -

Top Heroes

-
-
-
-

{{hero.name}}

-
-
-
- - - -@Component({ - selector: 'my-app', - template: ` -

{{title}}

- Dashboard - Heroes - - `, - styles: [` - .router-link {padding: 5px;text-decoration: none;} - .router-link:visited, .router-link:link {color: #444;} - .router-link:hover {color: white; background-color: #1171a3; - text-decoration: none;} - .router-link.router-link-active {color: white; - background-color: #52b9e9; text-decoration: none;} - `], - directives: [ROUTER_DIRECTIVES] -}) - - - -

Top Heroes

-
-
-
-

{{hero.name}}

-
-
-
- - - -
-

My Heroes

-
    -
  • - {{hero.id}} {{hero.name}} -
  • -
-
-

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

- -
-
- - - -h2 { color: #444; font-weight: lighter; } -body { margin: 2em; } -body, input[text], button { color: #888; font-family: Cambria, Georgia; } -button {padding: 0.2em; font-size: 14px} - \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts-snippets/app/main.pt4.ts b/public/docs/_examples/toh-5/ts-snippets/app/main.pt4.ts deleted file mode 100644 index f7ba365121..0000000000 --- a/public/docs/_examples/toh-5/ts-snippets/app/main.pt4.ts +++ /dev/null @@ -1,13 +0,0 @@ -// #docregion -import {bootstrap} from 'angular2/angular2'; -import {AppComponent} from './app.component'; -// #docregion import-hero-service -import {HeroService} from './hero.service'; -// #enddocregion import-hero-service -bootstrap(AppComponent, [HeroService]); -// #enddocregion - -// #docregion import-router -import {Router} from 'angular2/router'; -import {Routes} from './route.config'; -// #enddocregion import-router \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts-snippets/app/route.config.pt4.ts b/public/docs/_examples/toh-5/ts-snippets/app/route.config.pt4.ts deleted file mode 100644 index 8ba6169c5c..0000000000 --- a/public/docs/_examples/toh-5/ts-snippets/app/route.config.pt4.ts +++ /dev/null @@ -1,50 +0,0 @@ -// #docregion first-route -import {HeroesComponent} from './heroes.component'; - -export var Routes = { - heroes: { - path: '/, - as: 'Heroes', - component: HeroesComponent - } -}; - -export const APP_ROUTES = Object.keys(Routes).map(r => Routes[r]); -// #enddocregion first-route - -// #docregion dashboard-route -import {HeroesComponent} from './heroes.component'; -import {DashboardComponent} from './dashboard.component'; - -export var Routes = { - dashboard: { - path: '/', - as: 'Dashboard', - component: DashboardComponent - }, - heroes: { - path: '/heroes', - as: 'Heroes', - component: HeroesComponent - } -}; - -export const APP_ROUTES = Object.keys(Routes).map(r => Routes[r]); -// #enddocregion dashboard-route - -// #docregion route-parameter-import -import {HeroDetailComponent} from './hero-detail.component'; -// #enddocregion route-parameter-import -// #docregion route-parameter-detail -detail: { - path: '/detail/:id', - as: 'Detail', - component: HeroDetailComponent -} -// #docregion route-parameter-detail - -// #docregion router-navigate-method -gotoDetail(hero: Hero) { - this._router.navigate([`/${Routes.detail.as}`, { id: hero.id }]); -} -// #docregion router-navigate-method \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/app.component.1.js b/public/docs/_examples/toh-5/ts/app/app.component.1.js new file mode 100644 index 0000000000..c6e443c2af --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/app.component.1.js @@ -0,0 +1,54 @@ +System.register(['angular2/core', './hero.service', './heroes.component', 'angular2/router'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, hero_service_1, heroes_component_1, router_1; + var AppComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }, + function (heroes_component_1_1) { + heroes_component_1 = heroes_component_1_1; + }, + function (router_1_1) { + router_1 = router_1_1; + }], + execute: function() { + // #docregion + AppComponent = (function () { + function AppComponent() { + this.title = 'Tour of Heroes'; + } + AppComponent = __decorate([ + core_1.Component({ + selector: 'my-app', + template: "\n

{{title}}

\n \n ", + directives: [heroes_component_1.HeroesComponent], + providers: [ + // #enddocregion + router_1.ROUTER_PROVIDERS, + // #docregion + hero_service_1.HeroService + ] + }), + __metadata('design:paramtypes', []) + ], AppComponent); + return AppComponent; + })(); + exports_1("AppComponent", AppComponent); + } + } +}); +// #enddocregion +//# sourceMappingURL=app.component.1.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/app.component.1.ts b/public/docs/_examples/toh-5/ts/app/app.component.1.ts new file mode 100644 index 0000000000..e0104a019c --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/app.component.1.ts @@ -0,0 +1,30 @@ +// #docplaster +// #docregion +import { Component } from 'angular2/core'; +import { HeroService } from './hero.service'; +import { HeroesComponent } from './heroes.component'; +// #enddocregion + +// For testing only +import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router'; + +// #docregion + +@Component({ + selector: 'my-app', + template: ` +

{{title}}

+ + `, + directives: [HeroesComponent], + providers: [ +// #enddocregion + ROUTER_PROVIDERS, +// #docregion + HeroService + ] +}) +export class AppComponent { + title = 'Tour of Heroes'; +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/app.component.2.js b/public/docs/_examples/toh-5/ts/app/app.component.2.js new file mode 100644 index 0000000000..f333a301b6 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/app.component.2.js @@ -0,0 +1,61 @@ +System.register(['angular2/core', 'angular2/router', './hero.service', './heroes.component'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, router_1, hero_service_1, heroes_component_1; + var AppComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (router_1_1) { + router_1 = router_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }, + function (heroes_component_1_1) { + heroes_component_1 = heroes_component_1_1; + }], + execute: function() { + AppComponent = (function () { + function AppComponent() { + this.title = 'Tour of Heroes'; + } + AppComponent = __decorate([ + core_1.Component({ + selector: 'my-app', + // #docregion template + template: "\n

{{title}}

\n Heroes\n \n ", + // #enddocregion template + // #docregion directives-and-providers + directives: [router_1.ROUTER_DIRECTIVES], + providers: [ + router_1.ROUTER_PROVIDERS, + hero_service_1.HeroService + ] + }), + router_1.RouteConfig([ + { + path: '/heroes', + name: 'Heroes', + component: heroes_component_1.HeroesComponent + } + ]), + __metadata('design:paramtypes', []) + ], AppComponent); + return AppComponent; + })(); + exports_1("AppComponent", AppComponent); + } + } +}); +// #enddocregion +//# sourceMappingURL=app.component.2.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/app.component.2.ts b/public/docs/_examples/toh-5/ts/app/app.component.2.ts new file mode 100644 index 0000000000..17ce7e9412 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/app.component.2.ts @@ -0,0 +1,40 @@ +// #docplaster +// #docregion +import { Component } from 'angular2/core'; +// #docregion import-router +import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router'; +// #enddocregion import-router + +import { HeroService } from './hero.service'; +import { HeroesComponent } from './heroes.component'; + +@Component({ + selector: 'my-app', +// #docregion template + template: ` +

{{title}}

+ Heroes + + `, +// #enddocregion template +// #docregion directives-and-providers + directives: [ROUTER_DIRECTIVES], + providers: [ + ROUTER_PROVIDERS, + HeroService + ] + // #enddocregion directives-and-providers +}) +// #docregion route-config +@RouteConfig([ + { + path: '/heroes', + name: 'Heroes', + component: HeroesComponent + } +]) +// #enddocregion route-config +export class AppComponent { + title = 'Tour of Heroes'; +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/app.component.css b/public/docs/_examples/toh-5/ts/app/app.component.css new file mode 100644 index 0000000000..137e9be7be --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/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/ts/app/app.component.js b/public/docs/_examples/toh-5/ts/app/app.component.js new file mode 100644 index 0000000000..9d46c7c50b --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/app.component.js @@ -0,0 +1,85 @@ +System.register(['angular2/core', 'angular2/router', './hero.service', './dashboard.component', './heroes.component', './hero-detail.component'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, router_1, hero_service_1, dashboard_component_1, heroes_component_1, hero_detail_component_1; + var AppComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (router_1_1) { + router_1 = router_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }, + function (dashboard_component_1_1) { + dashboard_component_1 = dashboard_component_1_1; + }, + function (heroes_component_1_1) { + heroes_component_1 = heroes_component_1_1; + }, + function (hero_detail_component_1_1) { + hero_detail_component_1 = hero_detail_component_1_1; + }], + execute: function() { + // #enddocregion hero-detail-import + AppComponent = (function () { + function AppComponent() { + this.title = 'Tour of Heroes'; + } + AppComponent = __decorate([ + core_1.Component({ + selector: 'my-app', + // #docregion template + template: "\n

{{title}}

\n \n \n ", + // #enddocregion template + // #docregion style-urls + styleUrls: ['app/app.component.css'], + // #enddocregion style-urls + directives: [router_1.ROUTER_DIRECTIVES], + providers: [ + router_1.ROUTER_PROVIDERS, + hero_service_1.HeroService + ] + }), + router_1.RouteConfig([ + // #docregion dashboard-route + { + path: '/dashboard', + name: 'Dashboard', + component: dashboard_component_1.DashboardComponent, + useAsDefault: true + }, + // #enddocregion dashboard-route + // #docregion hero-detail-route + { + path: '/detail/:id', + name: 'HeroDetail', + component: hero_detail_component_1.HeroDetailComponent + }, + // #enddocregion hero-detail-route + { + path: '/heroes', + name: 'Heroes', + component: heroes_component_1.HeroesComponent + } + ]), + __metadata('design:paramtypes', []) + ], AppComponent); + return AppComponent; + })(); + exports_1("AppComponent", AppComponent); + } + } +}); +// #enddocregion +//# sourceMappingURL=app.component.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/app.component.ts b/public/docs/_examples/toh-5/ts/app/app.component.ts new file mode 100644 index 0000000000..df9985b5ee --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/app.component.ts @@ -0,0 +1,59 @@ +// #docplaster +// #docregion +import { Component } from 'angular2/core'; +import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router'; + +import { HeroService } from './hero.service'; +import { DashboardComponent } from './dashboard.component'; +import { HeroesComponent } from './heroes.component'; +// #docregion hero-detail-import +import { HeroDetailComponent } from './hero-detail.component'; +// #enddocregion hero-detail-import + +@Component({ + selector: 'my-app', +// #docregion template + template: ` +

{{title}}

+ + + `, +// #enddocregion template +// #docregion style-urls + styleUrls: ['app/app.component.css'], +// #enddocregion style-urls + directives: [ROUTER_DIRECTIVES], + providers: [ + ROUTER_PROVIDERS, + HeroService + ] +}) +@RouteConfig([ +// #docregion dashboard-route + { + path: '/dashboard', + name: 'Dashboard', + component: DashboardComponent, + useAsDefault: true + }, +// #enddocregion dashboard-route +// #docregion hero-detail-route + { + path: '/detail/:id', + name: 'HeroDetail', + component: HeroDetailComponent + }, +// #enddocregion hero-detail-route + { + path: '/heroes', + name: 'Heroes', + component: HeroesComponent + } +]) +export class AppComponent { + title = 'Tour of Heroes'; +} +// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.1.js b/public/docs/_examples/toh-5/ts/app/dashboard.component.1.js new file mode 100644 index 0000000000..67c981beba --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.1.js @@ -0,0 +1,35 @@ +System.register(['angular2/core'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1; + var DashboardComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }], + execute: function() { + DashboardComponent = (function () { + function DashboardComponent() { + } + DashboardComponent = __decorate([ + core_1.Component({ + selector: 'my-dashboard', + template: '

My Dashboard

' + }), + __metadata('design:paramtypes', []) + ], DashboardComponent); + return DashboardComponent; + })(); + exports_1("DashboardComponent", DashboardComponent); + } + } +}); +//# sourceMappingURL=dashboard.component.1.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts new file mode 100644 index 0000000000..eae02d1e95 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.1.ts @@ -0,0 +1,8 @@ +// #docregion +import { Component } from 'angular2/core'; + +@Component({ + selector: 'my-dashboard', + template: '

My Dashboard

' +}) +export class DashboardComponent { } diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.2.js b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.js new file mode 100644 index 0000000000..01295f9c5e --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.js @@ -0,0 +1,48 @@ +System.register(['angular2/core', './hero.service'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, hero_service_1; + var DashboardComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }], + execute: function() { + // #enddocregion imports + DashboardComponent = (function () { + function DashboardComponent(_heroService) { + this._heroService = _heroService; + this.heroes = []; + } + DashboardComponent.prototype.ngOnInit = function () { + var _this = this; + this._heroService.getHeroes() + .then(function (heroes) { return _this.heroes = heroes.slice(1, 5); }); + }; + DashboardComponent.prototype.gotoDetail = function () { }; + DashboardComponent = __decorate([ + core_1.Component({ + selector: 'my-dashboard', + templateUrl: 'app/dashboard.component.html' + }), + __metadata('design:paramtypes', [hero_service_1.HeroService]) + ], DashboardComponent); + return DashboardComponent; + })(); + exports_1("DashboardComponent", DashboardComponent); + } + } +}); +// #enddocregion component +//# sourceMappingURL=dashboard.component.2.js.map \ No newline at end of file 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 new file mode 100644 index 0000000000..896c7314a0 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.2.ts @@ -0,0 +1,27 @@ +// #docplaster +// #docregion imports +import { Component, OnInit } from 'angular2/core'; + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; +// #enddocregion imports + +@Component({ + selector: 'my-dashboard', + templateUrl: 'app/dashboard.component.html' +}) +// #docregion component +export class DashboardComponent implements OnInit { + + heroes: Hero[] = []; + + constructor(private _heroService: HeroService) { } + + ngOnInit() { + this._heroService.getHeroes() + .then(heroes => this.heroes = heroes.slice(1,5)); + } + + gotoDetail(){ /* not implemented yet */} +} +// #enddocregion component diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.css b/public/docs/_examples/toh-5/ts/app/dashboard.component.css new file mode 100644 index 0000000000..9ce340d052 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/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 0em; +} +.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/ts/app/dashboard.component.html b/public/docs/_examples/toh-5/ts/app/dashboard.component.html new file mode 100644 index 0000000000..8cc8ce9242 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.html @@ -0,0 +1,11 @@ + +

Top Heroes

+
+ +
+ +
+

{{hero.name}}

+
+
+
diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.js b/public/docs/_examples/toh-5/ts/app/dashboard.component.js new file mode 100644 index 0000000000..ecdac6d788 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.js @@ -0,0 +1,59 @@ +System.register(['angular2/core', 'angular2/router', './hero.service'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, router_1, hero_service_1; + var DashboardComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (router_1_1) { + router_1 = router_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }], + execute: function() { + DashboardComponent = (function () { + // #docregion ctor + function DashboardComponent(_router, _heroService) { + this._router = _router; + this._heroService = _heroService; + this.heroes = []; + } + // #enddocregion ctor + DashboardComponent.prototype.ngOnInit = function () { + var _this = this; + this._heroService.getHeroes() + .then(function (heroes) { return _this.heroes = heroes.slice(1, 5); }); + }; + // #docregion goto-detail + DashboardComponent.prototype.gotoDetail = function (hero) { + var link = ['HeroDetail', { id: hero.id }]; + this._router.navigate(link); + }; + DashboardComponent = __decorate([ + core_1.Component({ + selector: 'my-dashboard', + templateUrl: 'app/dashboard.component.html', + // #docregion css + styleUrls: ['app/dashboard.component.css'] + }), + __metadata('design:paramtypes', [router_1.Router, hero_service_1.HeroService]) + ], DashboardComponent); + return DashboardComponent; + })(); + exports_1("DashboardComponent", DashboardComponent); + } + } +}); +// #enddocregion +//# sourceMappingURL=dashboard.component.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/dashboard.component.ts b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts new file mode 100644 index 0000000000..ee1fe7ae57 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/dashboard.component.ts @@ -0,0 +1,42 @@ +// #docplaster +// #docregion +import { Component, OnInit } from 'angular2/core'; +// #docregion import-router +import { Router } from 'angular2/router'; +// #enddocregion import-router + +import { Hero } from './hero'; +import { HeroService } from './hero.service'; + +@Component({ + selector: 'my-dashboard', + templateUrl: 'app/dashboard.component.html', + // #docregion css + styleUrls: ['app/dashboard.component.css'] + // #enddocregion css +}) +// #docregion component +export class DashboardComponent implements OnInit { + + heroes: Hero[] = []; + +// #docregion ctor + constructor( + private _router: Router, + private _heroService: HeroService) { + } +// #enddocregion ctor + + ngOnInit() { + this._heroService.getHeroes() + .then(heroes => this.heroes = heroes.slice(1,5)); + } + + // #docregion goto-detail + gotoDetail(hero: Hero) { + let link = ['HeroDetail', { id: hero.id }]; + this._router.navigate(link); + } + // #enddocregion goto-detail +} +// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.css b/public/docs/_examples/toh-5/ts/app/hero-detail.component.css new file mode 100644 index 0000000000..9b2b954d64 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero-detail.component.css @@ -0,0 +1,25 @@ +/* #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; +} \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.html b/public/docs/_examples/toh-5/ts/app/hero-detail.component.html new file mode 100644 index 0000000000..cf96fc2169 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/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/ts/app/hero-detail.component.js b/public/docs/_examples/toh-5/ts/app/hero-detail.component.js new file mode 100644 index 0000000000..afb890cc46 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero-detail.component.js @@ -0,0 +1,68 @@ +System.register(['angular2/core', 'angular2/router', './hero.service'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, router_1, hero_service_1; + var HeroDetailComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (router_1_1) { + router_1 = router_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }], + execute: function() { + // #enddocregion import-hero-service + // #docregion extract-template + HeroDetailComponent = (function () { + // #docregion ctor + function HeroDetailComponent(_heroService, _routeParams) { + this._heroService = _heroService; + this._routeParams = _routeParams; + } + // #enddocregion ctor + // #docregion ng-oninit + HeroDetailComponent.prototype.ngOnInit = function () { + var _this = this; + // #docregion get-id + var id = +this._routeParams.get('id'); + // #enddocregion get-id + this._heroService.getHero(id) + .then(function (hero) { return _this.hero = hero; }); + }; + // #enddocregion ng-oninit + // #docregion go-back + HeroDetailComponent.prototype.goBack = function () { + window.history.back(); + }; + HeroDetailComponent = __decorate([ + core_1.Component({ + selector: 'my-hero-detail', + // #docregion template-url + templateUrl: 'app/hero-detail.component.html', + // #enddocregion template-url + // #enddocregion v2 + styleUrls: ['app/hero-detail.component.css'], + inputs: ['hero'] + }), + __metadata('design:paramtypes', [hero_service_1.HeroService, router_1.RouteParams]) + ], HeroDetailComponent); + return HeroDetailComponent; + })(); + exports_1("HeroDetailComponent", HeroDetailComponent); + } + } +}); +// #enddocregion v2 +// #enddocregion +//# sourceMappingURL=hero-detail.component.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts new file mode 100644 index 0000000000..1c06a4ee46 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero-detail.component.ts @@ -0,0 +1,57 @@ +// #docplaster +// #docregion +// #docregion v2 +// #docregion import-oninit +import { Component, OnInit } from 'angular2/core'; +// #enddocregion import-oninit +// #docregion import-route-params +import {RouteParams} from 'angular2/router'; +// #enddocregion import-route-params + +import { Hero } from './hero'; +// #docregion import-hero-service +import { HeroService } from './hero.service'; +// #enddocregion import-hero-service + +// #docregion extract-template +@Component({ + selector: 'my-hero-detail', + // #docregion template-url + templateUrl: 'app/hero-detail.component.html', + // #enddocregion template-url +// #enddocregion v2 + styleUrls: ['app/hero-detail.component.css'], + inputs: ['hero'] +// #docregion v2 +}) +// #enddocregion extract-template +// #docregion implement +export class HeroDetailComponent implements OnInit { +// #enddocregion implement + hero: Hero; + +// #docregion ctor + constructor( + private _heroService: HeroService, + private _routeParams: RouteParams) { + } +// #enddocregion ctor + +// #docregion ng-oninit + ngOnInit() { + // #docregion get-id + let id = +this._routeParams.get('id'); + // #enddocregion get-id + this._heroService.getHero(id) + .then(hero => this.hero = hero); + } +// #enddocregion ng-oninit + +// #docregion go-back + goBack() { + window.history.back(); + } +// #enddocregion go-back +} +// #enddocregion v2 +// #enddocregion diff --git a/public/docs/_examples/toh-5/ts/app/hero.js b/public/docs/_examples/toh-5/ts/app/hero.js new file mode 100644 index 0000000000..6a4d7f1427 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero.js @@ -0,0 +1,8 @@ +System.register([], function(exports_1) { + return { + setters:[], + execute: function() { + } + } +}); +//# sourceMappingURL=hero.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero.service.js b/public/docs/_examples/toh-5/ts/app/hero.service.js new file mode 100644 index 0000000000..0db32e5aec --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero.service.js @@ -0,0 +1,51 @@ +System.register(['./mock-heroes', 'angular2/core'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var mock_heroes_1, core_1; + var HeroService; + return { + setters:[ + function (mock_heroes_1_1) { + mock_heroes_1 = mock_heroes_1_1; + }, + function (core_1_1) { + core_1 = core_1_1; + }], + execute: function() { + HeroService = (function () { + function HeroService() { + } + HeroService.prototype.getHeroes = function () { + return Promise.resolve(mock_heroes_1.HEROES); + }; + // See the "Take it slow" appendix + HeroService.prototype.getHeroesSlowly = function () { + return new Promise(function (resolve) { + return setTimeout(function () { return resolve(mock_heroes_1.HEROES); }, 2000); + } // 2 seconds + // 2 seconds + ); + }; + //#docregion get-hero + HeroService.prototype.getHero = function (id) { + return Promise.resolve(mock_heroes_1.HEROES).then(function (heroes) { return heroes.filter(function (hero) { return hero.id === id; })[0]; }); + }; + HeroService = __decorate([ + core_1.Injectable(), + __metadata('design:paramtypes', []) + ], HeroService); + return HeroService; + })(); + exports_1("HeroService", HeroService); + } + } +}); +// #enddocregion +//# sourceMappingURL=hero.service.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero.service.ts b/public/docs/_examples/toh-5/ts/app/hero.service.ts new file mode 100644 index 0000000000..a55f71ec95 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero.service.ts @@ -0,0 +1,28 @@ +// #docplaster +// #docregion +import { Hero } from './hero'; +import { HEROES } from './mock-heroes'; +import { Injectable } from 'angular2/core'; + +@Injectable() +export class HeroService { + getHeroes() { + return Promise.resolve(HEROES); + } + + // See the "Take it slow" appendix + getHeroesSlowly() { + return new Promise(resolve => + setTimeout(()=>resolve(HEROES), 2000) // 2 seconds + ); + } + + //#docregion get-hero + getHero(id: number) { + return Promise.resolve(HEROES).then( + heroes => heroes.filter(hero => hero.id === id)[0] + ); + } + //#enddocregion get-hero +} +// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/hero.ts b/public/docs/_examples/toh-5/ts/app/hero.ts new file mode 100644 index 0000000000..a61b497759 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/hero.ts @@ -0,0 +1,4 @@ +export interface Hero { + id: number; + name: string; +} diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.css b/public/docs/_examples/toh-5/ts/app/heroes.component.css new file mode 100644 index 0000000000..f74c0e1642 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/heroes.component.css @@ -0,0 +1,47 @@ +/* #docregion */ +.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 0em; + height: 1.6em; + border-radius: 4px; +} +.heroes li.selected:hover { + color: white; +} +.heroes li:hover { + color: #607D8B; + background-color: #EEE; + left: .1em; +} +.heroes .text { + position: relative; + top: -3px; +} +.heroes .badge { + display: inline-block; + font-size: small; + color: white; + padding: 0.8em 0.7em 0em 0.7em; + background-color: #607D8B; + line-height: 1em; + position: relative; + left: -1px; + top: -4px; + height: 1.8em; + margin-right: .8em; + border-radius: 4px 0px 0px 4px; +} \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.html b/public/docs/_examples/toh-5/ts/app/heroes.component.html new file mode 100644 index 0000000000..9bcd2ba4e8 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/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/ts/app/heroes.component.js b/public/docs/_examples/toh-5/ts/app/heroes.component.js new file mode 100644 index 0000000000..9ba5693e11 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/heroes.component.js @@ -0,0 +1,65 @@ +System.register(['angular2/core', 'angular2/router', './hero-detail.component', './hero.service'], function(exports_1) { + var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); + }; + var core_1, router_1, hero_detail_component_1, hero_service_1; + var HeroesComponent; + return { + setters:[ + function (core_1_1) { + core_1 = core_1_1; + }, + function (router_1_1) { + router_1 = router_1_1; + }, + function (hero_detail_component_1_1) { + hero_detail_component_1 = hero_detail_component_1_1; + }, + function (hero_service_1_1) { + hero_service_1 = hero_service_1_1; + }], + execute: function() { + // #docregion metadata + // #docregion heroes-component-renaming + HeroesComponent = (function () { + function HeroesComponent(_router, _heroService) { + this._router = _router; + this._heroService = _heroService; + } + HeroesComponent.prototype.getHeroes = function () { + var _this = this; + this._heroService.getHeroes().then(function (heroes) { return _this.heroes = heroes; }); + }; + HeroesComponent.prototype.ngOnInit = function () { + this.getHeroes(); + }; + HeroesComponent.prototype.onSelect = function (hero) { this.selectedHero = hero; }; + HeroesComponent.prototype.gotoDetail = function () { + this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]); + }; + HeroesComponent = __decorate([ + core_1.Component({ + selector: 'my-heroes', + // #enddocregion heroes-component-renaming + templateUrl: 'app/heroes.component.html', + styleUrls: ['app/heroes.component.css'], + directives: [hero_detail_component_1.HeroDetailComponent] + }), + __metadata('design:paramtypes', [router_1.Router, hero_service_1.HeroService]) + ], HeroesComponent); + return HeroesComponent; + })(); + exports_1("HeroesComponent", HeroesComponent); + } + } +}); +// #enddocregion heroes-component-renaming +// #enddocregion class +// #enddocregion +//# sourceMappingURL=heroes.component.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/app/heroes.component.ts new file mode 100644 index 0000000000..6cdb00bc83 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/heroes.component.ts @@ -0,0 +1,50 @@ +// #docplaster +// #docregion +import { Component, OnInit } from 'angular2/core'; +import { Router } from 'angular2/router'; + +import { Hero } from './hero'; +import { HeroDetailComponent } from './hero-detail.component'; +import { HeroService } from './hero.service'; + +// #docregion metadata +// #docregion heroes-component-renaming +@Component({ + selector: 'my-heroes', +// #enddocregion heroes-component-renaming + templateUrl: 'app/heroes.component.html', + styleUrls: ['app/heroes.component.css'], + directives: [HeroDetailComponent] +// #docregion heroes-component-renaming +}) +// #enddocregion heroes-component-renaming +// #enddocregion metadata +// #docregion class +// #docregion heroes-component-renaming +export class HeroesComponent implements OnInit { +// #enddocregion heroes-component-renaming + heroes: Hero[]; + selectedHero: Hero; + + constructor( + private _router: Router, + private _heroService: HeroService) { } + + getHeroes() { + this._heroService.getHeroes().then(heroes => this.heroes = heroes); + } + + ngOnInit() { + this.getHeroes(); + } + + onSelect(hero: Hero) { this.selectedHero = hero; } + + gotoDetail() { + this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]); + } +// #docregion heroes-component-renaming +} +// #enddocregion heroes-component-renaming +// #enddocregion class +// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/main.js b/public/docs/_examples/toh-5/ts/app/main.js new file mode 100644 index 0000000000..da70522909 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/main.js @@ -0,0 +1,16 @@ +System.register(['angular2/platform/browser', './app.component'], function(exports_1) { + var browser_1, app_component_1; + return { + setters:[ + function (browser_1_1) { + browser_1 = browser_1_1; + }, + function (app_component_1_1) { + app_component_1 = app_component_1_1; + }], + execute: function() { + browser_1.bootstrap(app_component_1.AppComponent); + } + } +}); +//# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/main.ts b/public/docs/_examples/toh-5/ts/app/main.ts new file mode 100644 index 0000000000..c469e18fd0 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/main.ts @@ -0,0 +1,4 @@ +import { bootstrap } from 'angular2/platform/browser'; +import { AppComponent } from './app.component'; + +bootstrap(AppComponent); \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/mock-heroes.js b/public/docs/_examples/toh-5/ts/app/mock-heroes.js new file mode 100644 index 0000000000..5c4882e9a4 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/mock-heroes.js @@ -0,0 +1,22 @@ +System.register([], function(exports_1) { + var HEROES; + return { + setters:[], + execute: function() { + exports_1("HEROES", HEROES = [ + { "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": "Dynama" }, + { "id": 18, "name": "Dr IQ" }, + { "id": 19, "name": "Magma" }, + { "id": 20, "name": "Tornado" } + ]); + } + } +}); +// #enddocregion +//# sourceMappingURL=mock-heroes.js.map \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/app/mock-heroes.ts b/public/docs/_examples/toh-5/ts/app/mock-heroes.ts new file mode 100644 index 0000000000..cdcba35097 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/app/mock-heroes.ts @@ -0,0 +1,16 @@ +// #docregion +import { Hero } from './hero'; + +export var HEROES: Hero[] = [ + {"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": "Dynama"}, + {"id": 18, "name": "Dr IQ"}, + {"id": 19, "name": "Magma"}, + {"id": 20, "name": "Tornado"} +]; +// #enddocregion \ No newline at end of file diff --git a/public/docs/_examples/toh-5/ts/index.html b/public/docs/_examples/toh-5/ts/index.html new file mode 100644 index 0000000000..821ef1a586 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/index.html @@ -0,0 +1,38 @@ + + + + + + + + Angular 2 Tour of Heroes + + + + + + + + + + + + + + + + + + + + + + + + Loading... + + diff --git a/public/docs/_examples/toh-5/ts/plnkr.json b/public/docs/_examples/toh-5/ts/plnkr.json new file mode 100644 index 0000000000..019630c28f --- /dev/null +++ b/public/docs/_examples/toh-5/ts/plnkr.json @@ -0,0 +1,9 @@ +{ + "description": "Tour of Heroes: Part 5", + "files":[ + "!**/*.d.ts", + "!**/*.js", + "!**/*.[1,2].*" + ], + "tags": ["tutorial", "tour", "heroes", "router"] +} diff --git a/public/docs/_examples/toh-5/ts/styles.css b/public/docs/_examples/toh-5/ts/styles.css new file mode 100644 index 0000000000..88ec8391d3 --- /dev/null +++ b/public/docs/_examples/toh-5/ts/styles.css @@ -0,0 +1,7 @@ +/* #docplaster */ +/* #docregion */ +h2 { color: #444; font-weight: lighter; } +body { margin: 2em; } +body, input[text], button { color: #888; font-family: Cambria, Georgia; } +button { padding: 0.2em; font-size: 14px} +* { font-family: Arial; } diff --git a/public/docs/_examples/tutorial/ts/app/dashboard.component.ts b/public/docs/_examples/tutorial/ts/app/dashboard.component.ts index 62bf854264..ae5f048a57 100644 --- a/public/docs/_examples/tutorial/ts/app/dashboard.component.ts +++ b/public/docs/_examples/tutorial/ts/app/dashboard.component.ts @@ -18,6 +18,7 @@ export class DashboardComponent implements OnInit { } gotoDetail(hero: Hero) { - this._router.navigate(['HeroDetail', { id: hero.id }]); + let link = ['HeroDetail', { id: hero.id }]; + this._router.navigate(link); } } diff --git a/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts b/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts index 5540704913..0014918b8b 100644 --- a/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts +++ b/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit} from 'angular2/core'; import {RouteParams} from 'angular2/router'; + import {Hero} from './hero'; import {HeroService} from './hero.service'; @@ -17,10 +18,8 @@ export class HeroDetailComponent implements OnInit { } ngOnInit() { - if (!this.hero) { - let id = +this._routeParams.get('id'); - this._heroService.getHero(id).then(hero => this.hero = hero); - } + let id = +this._routeParams.get('id'); + this._heroService.getHero(id).then(hero => this.hero = hero); } goBack() { diff --git a/public/docs/_examples/tutorial/ts/app/hero.service.ts b/public/docs/_examples/tutorial/ts/app/hero.service.ts index 45b4e25adf..c3d6bc0cee 100644 --- a/public/docs/_examples/tutorial/ts/app/hero.service.ts +++ b/public/docs/_examples/tutorial/ts/app/hero.service.ts @@ -1,14 +1,15 @@ import {Injectable} from 'angular2/core'; -import {HEROES} from './mock-heroes'; +import {HEROES} from './mock-heroes'; @Injectable() export class HeroService { - getHeroes() { - return Promise.resolve(HEROES); - } + getHeroes() { + return Promise.resolve(HEROES); + } getHero(id: number) { - return Promise.resolve(HEROES) - .then(heroes => heroes.filter(h => h.id === id)[0]); - } + return Promise.resolve(HEROES).then( + heroes => heroes.filter(hero => hero.id === id)[0] + ); + } } diff --git a/public/docs/ts/latest/guide/router.jade b/public/docs/ts/latest/guide/router.jade index 40536e4050..09c8ac4ae3 100644 --- a/public/docs/ts/latest/guide/router.jade +++ b/public/docs/ts/latest/guide/router.jade @@ -38,7 +38,13 @@ include ../../../../_includes/_util-fns up to a modular, multi-view design with child routes. Try that [live final version](/resources/live-examples/router/ts/plnkr.html). - +.l-sub-section + :marked + In plunker, to see routing changes in the browser address bar, + pop out the preview window by clicking this blue button in the upper right corner: + + pop out the window +:marked But first, an overview of router basics. .l-main-section diff --git a/public/docs/ts/latest/guide/server-communication.jade b/public/docs/ts/latest/guide/server-communication.jade index 479f4a7d94..2eed334a1f 100644 --- a/public/docs/ts/latest/guide/server-communication.jade +++ b/public/docs/ts/latest/guide/server-communication.jade @@ -204,7 +204,8 @@ figure.image-display We shouldn't expect `json()` to return the heroes array directly. The server we're calling always wraps JSON results in an object with a `data` property. We have to unwrap it to get the heroes. - This is conventional web api behavior, driven by security concerns. + This is conventional web api behavior, driven by + [security concerns](https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#Always_return_JSON_with_an_Object_on_the_outside). :marked ### Do not return the response object Our `getHeroes()` could have returned the `Observable`. diff --git a/public/docs/ts/latest/tutorial/_data.json b/public/docs/ts/latest/tutorial/_data.json index d127c8f089..e70d5aaa55 100644 --- a/public/docs/ts/latest/tutorial/_data.json +++ b/public/docs/ts/latest/tutorial/_data.json @@ -20,5 +20,9 @@ "toh-pt4": { "title": "Services", "intro": "We create a reusable service to manage our hero data calls" + }, + "toh-pt5": { + "title": "Routing", + "intro": "We add the Angular Component Router and learn to navigate among the views" } } \ No newline at end of file diff --git a/public/docs/ts/latest/tutorial/toh-pt4.jade b/public/docs/ts/latest/tutorial/toh-pt4.jade index de47528fd2..daffd1b6bc 100644 --- a/public/docs/ts/latest/tutorial/toh-pt4.jade +++ b/public/docs/ts/latest/tutorial/toh-pt4.jade @@ -110,7 +110,7 @@ code-example(format="." language="bash"). We already have mock `Hero` data sitting in the `AppComponent`. It doesn't belong there. It doesn't belong *here* either. We'll move the mock data to its own file. - Cut the the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`. + Cut the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`. We copy the `import {Hero} ...` statement as well because the heroes array uses the `Hero` interface. +makeExample('toh-4/ts/app/mock-heroes.ts', null, 'mock-heroes.ts (Heroes array)') diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade new file mode 100644 index 0000000000..e0ee08e1a5 --- /dev/null +++ b/public/docs/ts/latest/tutorial/toh-pt5.jade @@ -0,0 +1,686 @@ +include ../../../../_includes/_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 + :marked + In plunker, to see routing changes in the browser address bar, + pop out the preview window by clicking this blue button in the upper right corner: + + pop out the window + +.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 node_modules + .file app + .children + .file app.component.ts + .file hero.ts + .file hero-detail.component.ts + .file hero.service.ts + .file main.ts + .file mock-heroes.ts + .file index.html + .file package.json + .file tsconfig.json +:marked + ### Keep the app transpiling and running + Open a terminal/console window and enter the following command to + start the TypeScript compiler, start the server, and watch for changes: + +code-example(format="." language="bash"). + npm start + +:marked + The application runs and updates automatically as we continue to build the Tour of Heroes. + + ## 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.ts` file to `heroes.component.ts`. + * rename the `AppComponent` class to `HeroesComponent`. + * rename the selector `my-app` to `my-heroes`. + +:marked ++makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (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.ts`. + * define an `AppComponent` class. + * `export` it so we can reference it during bootstrapping in `main.ts`. + * 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/ts/app/app.component.1.ts', null, 'app/app.component.ts (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/ts/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/ts/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/ts/app/app.component.2.ts', 'import-router', 'app.component.ts (router imports)')(format=".") +:marked + Next we update the `directives` and `providers` metadata arrays to *include* the router assets. ++makeExample('toh-5/ts/app/app.component.2.ts', 'directives-and-providers', 'app.component.ts (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/ts/app/app.component.2.ts', 'route-config', 'app.component.ts (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/ts/app/app.component.2.ts', 'template', 'app.component.ts (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.htmll#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/ts/app/app.component.2.ts',null, 'app/app.component.ts (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/ts/app/dashboard.component.1.ts',null, 'app/dashboard.component.ts (v1)')(format=".") +:marked + We’ll come back and make it more useful later. + + ### Configure the dashboard route + Go back to `app.component.ts` 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/ts/app/app.component.ts','dashboard-route', 'app.component.ts (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/ts/app/app.component.ts','template', 'app.component.ts (template)')(format=".") +.l-sub-section + :marked + We nestled the two links within `