From af458737be802f3e5f897529ad39f25d33425dc0 Mon Sep 17 00:00:00 2001 From: Ward Bell Date: Thu, 31 Dec 2015 20:04:22 -0800 Subject: [PATCH] docs(router): add query params milestone Additional fixes suggested by recent issues. closes #637 --- .../router/ts/app/app.component.2.ts | 14 +- .../router/ts/app/app.component.3.ts | 8 +- public/docs/_examples/router/ts/app/boot.2.ts | 22 +- .../crisis-center.component.1.ts | 28 ++ .../crisis-center/crisis-center.component.ts | 8 - .../crisis-detail.component.1.ts | 92 +++++ .../crisis-center/crisis-detail.component.ts | 30 +- .../crisis-center/crisis-list.component.1.ts | 36 ++ .../crisis-center/crisis-list.component.ts | 11 +- .../ts/app/heroes/hero-detail.component.1.ts | 44 +++ .../ts/app/heroes/hero-detail.component.ts | 9 +- .../ts/app/heroes/hero-list.component.1.ts | 49 +++ .../ts/app/heroes/hero-list.component.ts | 38 +- public/docs/_examples/router/ts/index.1.html | 15 +- public/docs/_examples/router/ts/index.2.html | 37 ++ public/docs/_examples/router/ts/index.3.html | 37 ++ public/docs/_examples/router/ts/styles.css | 2 + public/docs/ts/latest/guide/router.jade | 366 ++++++++++++++---- .../devguide/router/selected-crisis.png | Bin 0 -> 14938 bytes .../images/devguide/router/selected-hero.png | Bin 0 -> 14032 bytes 20 files changed, 679 insertions(+), 167 deletions(-) create mode 100644 public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts create mode 100644 public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts create mode 100644 public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts create mode 100644 public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts create mode 100644 public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts create mode 100644 public/docs/_examples/router/ts/index.2.html create mode 100644 public/docs/_examples/router/ts/index.3.html create mode 100644 public/resources/images/devguide/router/selected-crisis.png create mode 100644 public/resources/images/devguide/router/selected-hero.png diff --git a/public/docs/_examples/router/ts/app/app.component.2.ts b/public/docs/_examples/router/ts/app/app.component.2.ts index 4ab0f7aaf2..ce4f3c1c53 100644 --- a/public/docs/_examples/router/ts/app/app.component.2.ts +++ b/public/docs/_examples/router/ts/app/app.component.2.ts @@ -6,11 +6,22 @@ import {Component} from 'angular2/core'; import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'; import {CrisisListComponent} from './crisis-list.component'; +// #enddocregion +/* +// Apparent Milestone 2 imports +// #docregion // #docregion hero-import import {HeroListComponent} from './heroes/hero-list.component'; import {HeroDetailComponent} from './heroes/hero-detail.component'; import {HeroService} from './heroes/hero.service'; // #enddocregion hero-import +// #enddocregion +*/ +// Actual Milestone 2 imports +import {HeroListComponent} from './heroes/hero-list.component.1'; +import {HeroDetailComponent} from './heroes/hero-detail.component.1'; +import {HeroService} from './heroes/hero.service'; +// #docregion @Component({ selector: 'my-app', @@ -45,6 +56,3 @@ import {HeroService} from './heroes/hero.service'; export class AppComponent { } // #enddocregion route-config // #enddocregion - -// #docregion child-router-link -// #enddocregion child-router-link diff --git a/public/docs/_examples/router/ts/app/app.component.3.ts b/public/docs/_examples/router/ts/app/app.component.3.ts index f57a57f351..9129e383bc 100644 --- a/public/docs/_examples/router/ts/app/app.component.3.ts +++ b/public/docs/_examples/router/ts/app/app.component.3.ts @@ -1,11 +1,10 @@ // #docplaster -// #docregion import {Component} from 'angular2/core'; import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'; -import {CrisisCenterComponent} from './crisis-center/crisis-center.component'; -import {HeroListComponent} from './heroes/hero-list.component'; -import {HeroDetailComponent} from './heroes/hero-detail.component'; +import {CrisisCenterComponent} from './crisis-center/crisis-center.component.1'; +import {HeroListComponent} from './heroes/hero-list.component.1'; +import {HeroDetailComponent} from './heroes/hero-detail.component.1'; import {DialogService} from './dialog.service'; import {HeroService} from './heroes/hero.service'; @@ -36,7 +35,6 @@ import {HeroService} from './heroes/hero.service'; Princess Crisis // #enddocregion princess-anchor */ -// #docregion // #docregion template template: `

Component Router

diff --git a/public/docs/_examples/router/ts/app/boot.2.ts b/public/docs/_examples/router/ts/app/boot.2.ts index 1451041616..244050a36a 100644 --- a/public/docs/_examples/router/ts/app/boot.2.ts +++ b/public/docs/_examples/router/ts/app/boot.2.ts @@ -3,36 +3,30 @@ // Also includes digression on HashPathStrategy (not used in the final app) // #docplaster -// #docregion v2 +// #docregion import {bootstrap} from 'angular2/platform/browser'; import {ROUTER_PROVIDERS} from 'angular2/router'; import {AppComponent} from './app.component'; -// #enddocregion v2 -// Add these symbols to register a `LocationStrategy` +// Add these symbols to override the `LocationStrategy` import {provide} from 'angular2/core'; import {LocationStrategy, HashLocationStrategy} from 'angular2/router'; -// #enddocregion hash-strategy - +// #enddocregion /* Can't use AppComponent ... but display as if we can -// #docregion v2, hash-strategy +// #docregion bootstrap(AppComponent, [ -// #enddocregion v2, hash-strategy +// #enddocregion */ // Actually use the v.2 component import {AppComponent as ac} from './app.component.2'; bootstrap(ac, [ -// #docregion v2, hash-strategy +// #docregion ROUTER_PROVIDERS, -// #enddocregion v2, hash-strategy -// #docregion hash-strategy provide(LocationStrategy, - {useClass: HashLocationStrategy}) // ~/#/crisis-center/ -// #enddocregion hash-strategy -// #docregion v2, hash-strategy + {useClass: HashLocationStrategy}) // .../#/crisis-center/ ]); -// #enddocregion v2, hash-strategy +// #enddocregion diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts new file mode 100644 index 0000000000..8efe443bc0 --- /dev/null +++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.1.ts @@ -0,0 +1,28 @@ +import {Component} from 'angular2/core'; +import {RouteConfig, RouterOutlet} from 'angular2/router'; + +import {CrisisListComponent} from './crisis-list.component.1'; +import {CrisisDetailComponent} from './crisis-detail.component.1'; +import {CrisisService} from './crisis.service'; + +// #docregion minus-imports +@Component({ + template: ` +

CRISIS CENTER

+ + `, + directives: [RouterOutlet], +// #docregion providers + providers: [CrisisService] +// #enddocregion providers +}) +// #docregion route-config +@RouteConfig([ + // #docregion default-route + {path:'/', name: 'CrisisCenter', component: CrisisListComponent, useAsDefault: true}, + // #enddocregion default-route + {path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent} +]) +// #enddocregion route-config +export class CrisisCenterComponent { } +// #enddocregion minus-imports diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts index 897d573d2d..77f30e1a28 100644 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts +++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-center.component.ts @@ -6,25 +6,17 @@ import {CrisisListComponent} from './crisis-list.component'; import {CrisisDetailComponent} from './crisis-detail.component'; import {CrisisService} from './crisis.service'; -// #docregion minus-imports @Component({ template: `

CRISIS CENTER

`, directives: [RouterOutlet], -// #docregion providers providers: [CrisisService] -// #enddocregion providers }) -// #docregion route-config @RouteConfig([ - // #docregion default-route {path:'/', name: 'CrisisCenter', component: CrisisListComponent, useAsDefault: true}, - // #enddocregion default-route {path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent} ]) -// #enddocregion route-config export class CrisisCenterComponent { } -// #enddocregion minus-imports // #enddocregion diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts new file mode 100644 index 0000000000..210563df59 --- /dev/null +++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-detail.component.1.ts @@ -0,0 +1,92 @@ +// #docplaster + +// #docregion +import {Component, OnInit} from 'angular2/core'; +import {Crisis, CrisisService} from './crisis.service'; +import {RouteParams, Router} from 'angular2/router'; +// #docregion routerCanDeactivate +import {CanDeactivate, ComponentInstruction} from 'angular2/router'; +import {DialogService} from '../dialog.service'; + +// #enddocregion routerCanDeactivate + +@Component({ + // #docregion template + template: ` +
+

"{{editName}}"

+
+ {{crisis.id}}
+
+ + +
+ + +
+ `, + // #enddocregion template + styles: ['input {width: 20em}'] +}) +// #docregion routerCanDeactivate, cancel-save +export class CrisisDetailComponent implements OnInit, CanDeactivate { + + crisis: Crisis; + editName: string; + +// #enddocregion routerCanDeactivate, cancel-save + constructor( + private _service: CrisisService, + private _router: Router, + private _routeParams: RouteParams, + private _dialog: DialogService + ) { } + + // #docregion ngOnInit + ngOnInit() { + let id = +this._routeParams.get('id'); + this._service.getCrisis(id).then(crisis => { + if (crisis) { + this.editName = crisis.name; + this.crisis = crisis; + } else { // id not found + this.gotoCrises(); + } + }); + } + // #enddocregion ngOnInit + + // #docregion routerCanDeactivate + routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any { + // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. + if (!this.crisis || this.crisis.name === this.editName) { + return true; + } + // Otherwise ask the user with the dialog service and return its + // promise which resolves to true or false when the user decides + return this._dialog.confirm('Discard changes?'); + } + // #enddocregion routerCanDeactivate + + // #docregion cancel-save + cancel() { + this.editName = this.crisis.name; + this.gotoCrises(); + } + + save() { + this.crisis.name = this.editName; + this.gotoCrises(); + } + // #enddocregion cancel-save + + // #docregion gotoCrises + gotoCrises() { + // Like Crisis Center

"{{editName}}"

@@ -25,16 +21,14 @@ import {DialogService} from '../dialog.service'; `, - // #enddocregion template styles: ['input {width: 20em}'] }) -// #docregion routerCanDeactivate, cancel-save + export class CrisisDetailComponent implements OnInit, CanDeactivate { crisis: Crisis; editName: string; -// #enddocregion routerCanDeactivate, cancel-save constructor( private _service: CrisisService, private _router: Router, @@ -42,7 +36,6 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate { private _dialog: DialogService ) { } - // #docregion ngOnInit ngOnInit() { let id = +this._routeParams.get('id'); this._service.getCrisis(id).then(crisis => { @@ -54,9 +47,7 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate { } }); } - // #enddocregion ngOnInit - // #docregion routerCanDeactivate routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any { // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged. if (!this.crisis || this.crisis.name === this.editName) { @@ -66,9 +57,7 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate { // promise which resolves to true or false when the user decides return this._dialog.confirm('Discard changes?'); } - // #enddocregion routerCanDeactivate - // #docregion cancel-save cancel() { this.editName = this.crisis.name; this.gotoCrises(); @@ -78,19 +67,16 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate { this.crisis.name = this.editName; this.gotoCrises(); } - // #enddocregion cancel-save // #docregion gotoCrises gotoCrises() { - let route = - // pass along the crisis id if available - // so that the CrisisList component can select that crisis - ['CrisisCenter', {id: this.crisis ? this.crisis.id : null} ] - - this._router.navigate(route); + let crisisId = this.crisis ? this.crisis.id : null; + // Pass along the hero id if available + // so that the CrisisListComponent can select that hero. + // Add a totally useless `foo` parameter for kicks. + // #docregion gotoCrises-navigate + this._router.navigate(['CrisisCenter', {id: crisisId, foo: 'foo'} ]); + // #enddocregion gotoCrises-navigate } // #enddocregion gotoCrises -// #docregion routerCanDeactivate, cancel-save } -// #enddocregion routerCanDeactivate, cancel-save -// #enddocregion diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts new file mode 100644 index 0000000000..5338092184 --- /dev/null +++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.1.ts @@ -0,0 +1,36 @@ +// #docplaster + +// #docregion +import {Component, OnInit} from 'angular2/core'; +import {Crisis, CrisisService} from './crisis.service'; +import {Router} from 'angular2/router'; + +@Component({ + // #docregion template + template: ` + + `, + // #enddocregion template +}) +export class CrisisListComponent implements OnInit { + crises: Crisis[]; + + constructor( + private _service: CrisisService, + private _router: Router) {} + + ngOnInit() { + this._service.getCrises().then(crises => this.crises = crises); + } + + // #docregion select + onSelect(crisis: Crisis) { + this._router.navigate(['CrisisDetail', { id: crisis.id }] ); + } + // #enddocregion select +} diff --git a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts index dc08f1e747..d4ac1a040c 100644 --- a/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts +++ b/public/docs/_examples/router/ts/app/crisis-center/crisis-list.component.ts @@ -18,7 +18,7 @@ import {Router, RouteParams} from 'angular2/router'; }) export class CrisisListComponent implements OnInit { crises: Crisis[]; - // #docregion isSelected + private _selectedId: number; constructor( @@ -27,19 +27,14 @@ export class CrisisListComponent implements OnInit { routeParams: RouteParams) { this._selectedId = +routeParams.get('id'); } - // #enddocregion isSelected + + isSelected(crisis: Crisis) { return crisis.id === this._selectedId; } ngOnInit() { this._service.getCrises().then(crises => this.crises = crises); } - // #docregion isSelected - isSelected(crisis: Crisis) { return crisis.id === this._selectedId; } - // #enddocregion isSelected - - // #docregion select onSelect(crisis: Crisis) { this._router.navigate( ['CrisisDetail', { id: crisis.id }] ); } - // #enddocregion select } diff --git a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts new file mode 100644 index 0000000000..96627686d5 --- /dev/null +++ b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.1.ts @@ -0,0 +1,44 @@ +// #docregion +import {Component, OnInit} from 'angular2/core'; +import {Hero, HeroService} from './hero.service'; +import {RouteParams, Router} from 'angular2/router'; + +@Component({ + template: ` +

HEROES

+
+

"{{hero.name}}"

+
+ {{hero.id}}
+
+ + +
+ +
+ `, +}) +export class HeroDetailComponent implements OnInit { + hero: Hero; + + // #docregion ctor + constructor( + private _router:Router, + private _routeParams:RouteParams, + private _service:HeroService){} + // #enddocregion ctor + + // #docregion ngOnInit + ngOnInit() { + let id = this._routeParams.get('id'); + this._service.getHero(id).then(hero => this.hero = hero); + } + // #enddocregion ngOnInit + + // #docregion gotoHeroes + gotoHeroes() { + // Like Heroes + this._router.navigate(['Heroes']); + } + // #enddocregion gotoHeroes +} diff --git a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts index 7d26ddafe7..eeccb1836b 100644 --- a/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts +++ b/public/docs/_examples/router/ts/app/heroes/hero-detail.component.ts @@ -37,8 +37,13 @@ export class HeroDetailComponent implements OnInit { // #docregion gotoHeroes gotoHeroes() { - // Heroes - this._router.navigate(['Heroes']); + let heroId = this.hero ? this.hero.id : null; + // Pass along the hero id if available + // so that the HeroList component can select that hero. + // Add a totally useless `foo` parameter for kicks. + // #docregion gotoHeroes-navigate + this._router.navigate(['Heroes', {id: heroId, foo: 'foo'} ]); + // #enddocregion gotoHeroes-navigate } // #enddocregion gotoHeroes } diff --git a/public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts b/public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts new file mode 100644 index 0000000000..78f5ad4cd4 --- /dev/null +++ b/public/docs/_examples/router/ts/app/heroes/hero-list.component.1.ts @@ -0,0 +1,49 @@ +// #docplaster + +// #docregion +// TODO SOMEDAY: Feature Componetized like HeroCenter +import {Component, OnInit} from 'angular2/core'; +import {Hero, HeroService} from './hero.service'; +import {Router} from 'angular2/router'; + +@Component({ + // #docregion template + template: ` +

HEROES

+ + ` + // #enddocregion template +}) +export class HeroListComponent implements OnInit { + heroes: Hero[]; + + // #docregion ctor + constructor( + private _router: Router, + private _service: HeroService) { } + // #enddocregion ctor + + ngOnInit() { + this._service.getHeroes().then(heroes => this.heroes = heroes) + } + + // #docregion select + onSelect(hero: Hero) { + // #docregion nav-to-detail + this._router.navigate( ['HeroDetail', { id: hero.id }] ); + // #enddocregion nav-to-detail + } + // #enddocregion select +} +// #enddocregion + +/* A link parameters array +// #docregion link-parameters-array +['HeroDetail', { id: hero.id }] // {id: 15} +// #enddocregion link-parameters-array +*/ \ No newline at end of file diff --git a/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts b/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts index 3a8de0408f..7957d8702c 100644 --- a/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts +++ b/public/docs/_examples/router/ts/app/heroes/hero-list.component.ts @@ -1,10 +1,12 @@ // #docplaster +// TODO SOMEDAY: Feature Componetized like CrisisCenter // #docregion -// TODO SOMEDAY: Feature Componetized like HeroCenter import {Component, OnInit} from 'angular2/core'; import {Hero, HeroService} from './hero.service'; -import {Router} from 'angular2/router'; +// #docregion import-route-params +import {Router, RouteParams} from 'angular2/router'; +// #enddocregion import-route-params @Component({ // #docregion template @@ -12,6 +14,7 @@ import {Router} from 'angular2/router';

HEROES