docs(router): samples and doc for new router (phase 1)
This commit is contained in:
parent
f513ee83c7
commit
2ccdd867d2
|
@ -25,6 +25,7 @@
|
|||
"@angular/http": "2.0.0-rc.0",
|
||||
"@angular/platform-browser": "2.0.0-rc.0",
|
||||
"@angular/platform-browser-dynamic": "2.0.0-rc.0",
|
||||
"@angular/router": "2.0.0-rc.0",
|
||||
"@angular/router-deprecated": "2.0.0-rc.0",
|
||||
"@angular/upgrade": "2.0.0-rc.0",
|
||||
|
||||
|
|
|
@ -7,14 +7,22 @@
|
|||
},
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@angular/common": "2.0.0-rc.0",
|
||||
"@angular/compiler": "2.0.0-rc.0",
|
||||
"@angular/core": "2.0.0-rc.0",
|
||||
"@angular/platform-browser": "2.0.0-rc.0",
|
||||
"@angular/platform-browser-dynamic": "2.0.0-rc.0",
|
||||
"@angular/common": "2.0.0-rc.0",
|
||||
"@angular/compiler": "2.0.0-rc.0",
|
||||
"@angular/core": "2.0.0-rc.0",
|
||||
"@angular/http": "2.0.0-rc.0",
|
||||
"@angular/platform-browser": "2.0.0-rc.0",
|
||||
"@angular/platform-browser-dynamic": "2.0.0-rc.0",
|
||||
"@angular/router": "2.0.0-rc.0",
|
||||
"@angular/router-deprecated": "2.0.0-rc.0",
|
||||
"@angular/upgrade": "2.0.0-rc.0",
|
||||
|
||||
"reflect-metadata": "0.1.3",
|
||||
"rxjs": "5.0.0-beta.6",
|
||||
"zone.js": "0.6.12"
|
||||
"zone.js": "0.6.12",
|
||||
|
||||
"angular2-in-memory-web-api": "0.0.6",
|
||||
"bootstrap": "^3.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^2.0.0",
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"@angular/http": "2.0.0-rc.0",
|
||||
"@angular/platform-browser": "2.0.0-rc.0",
|
||||
"@angular/platform-browser-dynamic": "2.0.0-rc.0",
|
||||
"@angular/router": "2.0.0-rc.0",
|
||||
"@angular/router-deprecated": "2.0.0-rc.0",
|
||||
"@angular/upgrade": "2.0.0-rc.0",
|
||||
|
||||
|
@ -26,7 +27,7 @@
|
|||
"rxjs": "5.0.0-beta.6",
|
||||
"zone.js": "^0.6.12",
|
||||
|
||||
"angular2-in-memory-web-api": "0.0.5",
|
||||
"angular2-in-memory-web-api": "0.0.6",
|
||||
"bootstrap": "^3.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
describe('Router', function () {
|
||||
|
||||
beforeAll(function () {
|
||||
browser.get('');
|
||||
});
|
||||
|
||||
function getPageStruct() {
|
||||
hrefEles = element.all(by.css('my-app a'));
|
||||
|
||||
return {
|
||||
hrefs: hrefEles,
|
||||
routerParent: element(by.css('my-app > undefined')),
|
||||
routerTitle: element(by.css('my-app > undefined > h2')),
|
||||
|
||||
crisisHref: hrefEles.get(0),
|
||||
crisisList: element.all(by.css('my-app > undefined > undefined li')),
|
||||
crisisDetail: element(by.css('my-app > undefined > undefined > div')),
|
||||
crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')),
|
||||
|
||||
heroesHref: hrefEles.get(1),
|
||||
heroesList: element.all(by.css('my-app > undefined li')),
|
||||
heroDetail: element(by.css('my-app > undefined > div')),
|
||||
heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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.crisisHref.getText()).toEqual("Crisis Center");
|
||||
expect(page.heroesHref.getText()).toEqual("Heroes");
|
||||
});
|
||||
|
||||
it('should be able to see crises center items', function () {
|
||||
var page = getPageStruct();
|
||||
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start");
|
||||
});
|
||||
|
||||
it('should be able to see hero items', function () {
|
||||
var page = getPageStruct();
|
||||
page.heroesHref.click().then(function() {
|
||||
expect(page.routerTitle.getText()).toContain('HEROES');
|
||||
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to toggle the views', function () {
|
||||
var page = getPageStruct();
|
||||
page.crisisHref.click().then(function() {
|
||||
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries");
|
||||
return page.heroesHref.click();
|
||||
}).then(function() {
|
||||
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to edit and save details from the crisis center view', function () {
|
||||
crisisCenterEdit(2, true);
|
||||
});
|
||||
|
||||
it('should be able to edit and cancel details from the crisis center view', function () {
|
||||
crisisCenterEdit(3, false);
|
||||
});
|
||||
|
||||
it('should be able to edit and save details from the heroes view', function () {
|
||||
var page = getPageStruct();
|
||||
var heroEle, heroText;
|
||||
page.heroesHref.click().then(function() {
|
||||
heroEle = page.heroesList.get(4);
|
||||
return heroEle.getText();
|
||||
}).then(function(text) {
|
||||
expect(text.length).toBeGreaterThan(0, 'should have some text');
|
||||
// remove leading id from text
|
||||
heroText = text.substr(text.indexOf(' ')).trim();
|
||||
return heroEle.click();
|
||||
}).then(function() {
|
||||
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries");
|
||||
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
|
||||
expect(page.heroDetailTitle.getText()).toContain(heroText);
|
||||
var inputEle = page.heroDetail.element(by.css('input'));
|
||||
return sendKeys(inputEle, '-foo');
|
||||
}).then(function() {
|
||||
expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo');
|
||||
var buttonEle = page.heroDetail.element(by.css('button'));
|
||||
return buttonEle.click();
|
||||
}).then(function() {
|
||||
expect(heroEle.getText()).toContain(heroText + '-foo');
|
||||
})
|
||||
});
|
||||
|
||||
function crisisCenterEdit(index, shouldSave) {
|
||||
var page = getPageStruct();
|
||||
var crisisEle, crisisText;
|
||||
page.crisisHref.click().then(function () {
|
||||
crisisEle = page.crisisList.get(index);
|
||||
return crisisEle.getText();
|
||||
}).then(function (text) {
|
||||
expect(text.length).toBeGreaterThan(0, 'should have some text');
|
||||
// remove leading id from text
|
||||
crisisText = text.substr(text.indexOf(' ')).trim();
|
||||
return crisisEle.click();
|
||||
}).then(function () {
|
||||
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries");
|
||||
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
|
||||
expect(page.crisisDetailTitle.getText()).toContain(crisisText);
|
||||
var inputEle = page.crisisDetail.element(by.css('input'));
|
||||
return sendKeys(inputEle, '-foo');
|
||||
}).then(function () {
|
||||
expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo');
|
||||
var buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
|
||||
return buttonEle.click();
|
||||
}).then(function () {
|
||||
if (shouldSave) {
|
||||
expect(crisisEle.getText()).toContain(crisisText + '-foo');
|
||||
} else {
|
||||
expect(crisisEle.getText()).not.toContain(crisisText + '-foo');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,43 @@
|
|||
/* First version */
|
||||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion import-router
|
||||
import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
|
||||
// #enddocregion import-router
|
||||
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
// #enddocregion template
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
// #enddocregion
|
||||
/*
|
||||
// #docregion route-config
|
||||
@Component({ ... })
|
||||
// #enddocregion route-config
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
// #docregion route-defs
|
||||
{path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent},
|
||||
{path: '/heroes', name: 'Heroes', component: HeroListComponent}
|
||||
// #enddocregion route-defs
|
||||
])
|
||||
export class AppComponent { }
|
||||
// #enddocregion route-config
|
||||
// #enddocregion
|
|
@ -0,0 +1,58 @@
|
|||
/* Second Heroes version */
|
||||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
|
||||
|
||||
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',
|
||||
template: `
|
||||
<h1>Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
providers: [HeroService],
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
// #enddocregion
|
||||
/*
|
||||
// #docregion route-config
|
||||
@Component({ ... })
|
||||
// #enddocregion route-config
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
// #docregion route-defs
|
||||
{path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent},
|
||||
{path: '/heroes', name: 'Heroes', component: HeroListComponent},
|
||||
// #docregion hero-detail-route
|
||||
{path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent}
|
||||
// #enddocregion hero-detail-route
|
||||
// #enddocregion route-defs
|
||||
])
|
||||
export class AppComponent { }
|
||||
// #enddocregion route-config
|
||||
// #enddocregion
|
|
@ -0,0 +1,53 @@
|
|||
// #docplaster
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
|
||||
|
||||
import {CrisisCenterComponent} from './crisis-center/crisis-center.component.1';
|
||||
|
||||
import {DialogService} from './dialog.service';
|
||||
import {HeroService} from './heroes/hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
// #enddocregion
|
||||
/* Typical link
|
||||
// #docregion h-anchor
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
// #enddocregion h-anchor
|
||||
*/
|
||||
/* Incomplete Crisis Center link when CC lacks a default
|
||||
// #docregion cc-anchor-fail
|
||||
// The link now fails with a "non-terminal link" error
|
||||
// #docregion cc-anchor-w-default
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
// #enddocregion cc-anchor-w-default
|
||||
// #enddocregion cc-anchor-fail
|
||||
*/
|
||||
/* Crisis Center link when CC lacks a default
|
||||
// #docregion cc-anchor-no-default
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisList']">Crisis Center</a>
|
||||
// #enddocregion cc-anchor-no-default
|
||||
*/
|
||||
/* Crisis Center Detail link
|
||||
// #docregion Dragon-anchor
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisDetail', {id:1}]">Dragon Crisis</a>
|
||||
// #enddocregion Dragon-anchor
|
||||
*/
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1 class="title">Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisList']">Crisis Center</a>
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisDetail', {id:1}]">Dragon Crisis</a>
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisDetail', {id:2}]">Shark Crisis</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
// #enddocregion template
|
||||
providers: [DialogService, HeroService],
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
@RouteConfig([
|
||||
{path: '/crisis-center/...', name: 'CrisisCenter', component: CrisisCenterComponent},
|
||||
])
|
||||
export class AppComponent { }
|
|
@ -0,0 +1,44 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
|
||||
|
||||
import {CrisisCenterComponent} from './crisis-center/crisis-center.component';
|
||||
import {HeroListComponent} from './heroes/hero-list.component';
|
||||
import {HeroDetailComponent} from './heroes/hero-detail.component';
|
||||
|
||||
import {DialogService} from './dialog.service';
|
||||
import {HeroService} from './heroes/hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1 class="title">Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
// #enddocregion template
|
||||
providers: [DialogService, HeroService],
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
|
||||
// #docregion route-config-cc
|
||||
{ // Crisis Center child route
|
||||
path: '/crisis-center/...',
|
||||
name: 'CrisisCenter',
|
||||
component: CrisisCenterComponent,
|
||||
useAsDefault: true
|
||||
},
|
||||
// #enddocregion route-config-cc
|
||||
|
||||
{path: '/heroes', name: 'Heroes', component: HeroListComponent},
|
||||
{path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent},
|
||||
])
|
||||
// #enddocregion route-config
|
||||
export class AppComponent { }
|
|
@ -0,0 +1,28 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, RouterOutlet} from '@angular/router-deprecated';
|
||||
|
||||
import {CrisisListComponent} from './crisis-list.component.1';
|
||||
import {CrisisDetailComponent} from './crisis-detail.component.1';
|
||||
import {CrisisService} from './crisis.service';
|
||||
|
||||
// #docregion minus-imports
|
||||
@Component({
|
||||
template: `
|
||||
<h2>CRISIS CENTER</h2>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
directives: [RouterOutlet],
|
||||
// #docregion providers
|
||||
providers: [CrisisService]
|
||||
// #enddocregion providers
|
||||
})
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
// #docregion default-route
|
||||
{path:'/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true},
|
||||
// #enddocregion default-route
|
||||
{path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
|
||||
])
|
||||
// #enddocregion route-config
|
||||
export class CrisisCenterComponent { }
|
||||
// #enddocregion minus-imports
|
|
@ -0,0 +1,22 @@
|
|||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, RouterOutlet} from '@angular/router-deprecated';
|
||||
|
||||
import {CrisisListComponent} from './crisis-list.component';
|
||||
import {CrisisDetailComponent} from './crisis-detail.component';
|
||||
import {CrisisService} from './crisis.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>CRISIS CENTER</h2>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
directives: [RouterOutlet],
|
||||
providers: [CrisisService]
|
||||
})
|
||||
@RouteConfig([
|
||||
{path:'/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true},
|
||||
{path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
|
||||
])
|
||||
export class CrisisCenterComponent { }
|
||||
// #enddocregion
|
|
@ -0,0 +1,94 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
// #docregion routerCanDeactivate
|
||||
import {CanDeactivate, ComponentInstruction} from '@angular/router-deprecated';
|
||||
import {DialogService} from '../dialog.service';
|
||||
|
||||
// #enddocregion routerCanDeactivate
|
||||
|
||||
@Component({
|
||||
// #docregion template
|
||||
template: `
|
||||
<div *ngIf="crisis">
|
||||
<h3>"{{editName}}"</h3>
|
||||
<div>
|
||||
<label>Id: </label>{{crisis.id}}</div>
|
||||
<div>
|
||||
<label>Name: </label>
|
||||
<input [(ngModel)]="editName" placeholder="name"/>
|
||||
</div>
|
||||
<p>
|
||||
<button (click)="save()">Save</button>
|
||||
<button (click)="cancel()">Cancel</button>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
// #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 <a [routerLink]="['CrisisList']">Crisis Center</a
|
||||
this._router.navigate(['CrisisList']);
|
||||
}
|
||||
// #enddocregion gotoCrises
|
||||
// #docregion routerCanDeactivate, cancel-save
|
||||
}
|
||||
// #enddocregion routerCanDeactivate, cancel-save
|
||||
// #enddocregion
|
|
@ -0,0 +1,84 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
import {CanDeactivate, ComponentInstruction} from '@angular/router-deprecated';
|
||||
import {DialogService} from '../dialog.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<div *ngIf="crisis">
|
||||
<h3>"{{editName}}"</h3>
|
||||
<div>
|
||||
<label>Id: </label>{{crisis.id}}</div>
|
||||
<div>
|
||||
<label>Name: </label>
|
||||
<input [(ngModel)]="editName" placeholder="name"/>
|
||||
</div>
|
||||
<p>
|
||||
<button (click)="save()">Save</button>
|
||||
<button (click)="cancel()">Cancel</button>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
styles: ['input {width: 20em}']
|
||||
})
|
||||
|
||||
export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
||||
|
||||
crisis: Crisis;
|
||||
editName: string;
|
||||
|
||||
constructor(
|
||||
private _service: CrisisService,
|
||||
private _router: Router,
|
||||
private _routeParams: RouteParams,
|
||||
private _dialog: DialogService
|
||||
) { }
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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?');
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.editName = this.crisis.name;
|
||||
this.gotoCrises();
|
||||
}
|
||||
|
||||
save() {
|
||||
this.crisis.name = this.editName;
|
||||
this.gotoCrises();
|
||||
}
|
||||
|
||||
// #docregion gotoCrises
|
||||
gotoCrises() {
|
||||
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(['CrisisList', {id: crisisId, foo: 'foo'} ]);
|
||||
// #enddocregion gotoCrises-navigate
|
||||
}
|
||||
// #enddocregion gotoCrises
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {Router} from '@angular/router-deprecated';
|
||||
|
||||
@Component({
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul class="items">
|
||||
<li *ngFor="let crisis of crises"
|
||||
(click)="onSelect(crisis)">
|
||||
<span class="badge">{{crisis.id}}</span> {{crisis.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #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
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {Router, RouteParams} from '@angular/router-deprecated';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ul class="items">
|
||||
<li *ngFor="let crisis of crises"
|
||||
[class.selected]="isSelected(crisis)"
|
||||
(click)="onSelect(crisis)">
|
||||
<span class="badge">{{crisis.id}}</span> {{crisis.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
export class CrisisListComponent implements OnInit {
|
||||
crises: Crisis[];
|
||||
|
||||
private _selectedId: number;
|
||||
|
||||
constructor(
|
||||
private _service: CrisisService,
|
||||
private _router: Router,
|
||||
routeParams: RouteParams) {
|
||||
this._selectedId = +routeParams.get('id');
|
||||
}
|
||||
|
||||
isSelected(crisis: Crisis) { return crisis.id === this._selectedId; }
|
||||
|
||||
ngOnInit() {
|
||||
this._service.getCrises().then(crises => this.crises = crises);
|
||||
}
|
||||
|
||||
onSelect(crisis: Crisis) {
|
||||
this._router.navigate( ['CrisisDetail', { id: crisis.id }] );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
export class Crisis {
|
||||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class CrisisService {
|
||||
getCrises() { return crisesPromise; }
|
||||
|
||||
getCrisis(id: number | string) {
|
||||
return crisesPromise
|
||||
.then(crises => crises.filter(c => c.id === +id)[0]);
|
||||
}
|
||||
|
||||
// #enddocregion
|
||||
|
||||
static nextCrisisId = 100;
|
||||
|
||||
addCrisis(name:string) {
|
||||
name = name.trim();
|
||||
if (name){
|
||||
let crisis = new Crisis(CrisisService.nextCrisisId++, name);
|
||||
crisesPromise.then(crises => crises.push(crisis));
|
||||
}
|
||||
}
|
||||
// #docregion
|
||||
}
|
||||
|
||||
var crises = [
|
||||
new Crisis(1, 'Dragon Burning Cities'),
|
||||
new Crisis(2, 'Sky Rains Great White Sharks'),
|
||||
new Crisis(3, 'Giant Asteroid Heading For Earth'),
|
||||
new Crisis(4, 'Procrastinators Meeting Delayed Again'),
|
||||
];
|
||||
|
||||
var crisesPromise = Promise.resolve(crises);
|
||||
// #enddocregion
|
|
@ -0,0 +1,10 @@
|
|||
// Initial empty version
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>CRISIS CENTER</h2>
|
||||
<p>Get your crisis here</p>`
|
||||
})
|
||||
export class CrisisListComponent { }
|
|
@ -0,0 +1,18 @@
|
|||
// #docregion
|
||||
import {Injectable} from '@angular/core';
|
||||
/**
|
||||
* Async modal dialog service
|
||||
* DialogService makes this app easier to test by faking this service.
|
||||
* TODO: better modal implemenation that doesn't use window.confirm
|
||||
*/
|
||||
@Injectable()
|
||||
export class DialogService {
|
||||
/**
|
||||
* Ask user to confirm an action. `message` explains the action and choices.
|
||||
* Returns promise resolving to `true`=confirm or `false`=cancel
|
||||
*/
|
||||
confirm(message?:string) {
|
||||
return new Promise<boolean>((resolve, reject) =>
|
||||
resolve(window.confirm(message || 'Is it OK?')));
|
||||
};
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/// Initial empty version
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<p>Get your heroes here</p>`
|
||||
})
|
||||
export class HeroListComponent { }
|
|
@ -0,0 +1,46 @@
|
|||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<div *ngIf="hero">
|
||||
<h3>"{{hero.name}}"</h3>
|
||||
<div>
|
||||
<label>Id: </label>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>Name: </label>
|
||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
||||
</div>
|
||||
<p>
|
||||
<button (click)="gotoHeroes()">Back</button>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
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 <a [routerLink]="['Heroes']">Heroes</a>
|
||||
this._router.navigate(['Heroes']);
|
||||
}
|
||||
// #enddocregion gotoHeroes
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<div *ngIf="hero">
|
||||
<h3>"{{hero.name}}"</h3>
|
||||
<div>
|
||||
<label>Id: </label>{{hero.id}}</div>
|
||||
<div>
|
||||
<label>Name: </label>
|
||||
<input [(ngModel)]="hero.name" placeholder="name"/>
|
||||
</div>
|
||||
<p>
|
||||
<button (click)="gotoHeroes()">Back</button>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
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() {
|
||||
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
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
// TODO SOMEDAY: Feature Componetized like HeroCenter
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
import {Router} from '@angular/router-deprecated';
|
||||
|
||||
@Component({
|
||||
// #docregion template
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<ul class="items">
|
||||
<li *ngFor="let hero of heroes"
|
||||
(click)="onSelect(hero)">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`
|
||||
// #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
|
||||
*/
|
|
@ -0,0 +1,53 @@
|
|||
// #docplaster
|
||||
|
||||
// TODO SOMEDAY: Feature Componetized like CrisisCenter
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
// #docregion import-route-params
|
||||
import {Router, RouteParams} from '@angular/router-deprecated';
|
||||
// #enddocregion import-route-params
|
||||
|
||||
@Component({
|
||||
// #docregion template
|
||||
template: `
|
||||
<h2>HEROES</h2>
|
||||
<ul class="items">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[class.selected]="isSelected(hero)"
|
||||
(click)="onSelect(hero)">
|
||||
<span class="badge">{{hero.id}}</span> {{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
export class HeroListComponent implements OnInit {
|
||||
heroes: Hero[];
|
||||
|
||||
// #docregion ctor
|
||||
private _selectedId: number;
|
||||
|
||||
constructor(
|
||||
private _service: HeroService,
|
||||
private _router: Router,
|
||||
routeParams: RouteParams) {
|
||||
this._selectedId = +routeParams.get('id');
|
||||
}
|
||||
// #enddocregion ctor
|
||||
|
||||
// #docregion isSelected
|
||||
isSelected(hero: Hero) { return hero.id === this._selectedId; }
|
||||
// #enddocregion isSelected
|
||||
|
||||
// #docregion select
|
||||
onSelect(hero: Hero) {
|
||||
this._router.navigate( ['HeroDetail', { id: hero.id }] );
|
||||
}
|
||||
// #enddocregion select
|
||||
|
||||
ngOnInit() {
|
||||
this._service.getHeroes().then(heroes => this.heroes = heroes)
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
|
@ -0,0 +1,27 @@
|
|||
// #docregion
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
export class Hero {
|
||||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class HeroService {
|
||||
getHeroes() { return heroesPromise; }
|
||||
|
||||
getHero(id: number | string) {
|
||||
return heroesPromise
|
||||
.then(heroes => heroes.filter(h => h.id === +id)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
var HEROES = [
|
||||
new Hero(11, 'Mr. Nice'),
|
||||
new Hero(12, 'Narco'),
|
||||
new Hero(13, 'Bombasto'),
|
||||
new Hero(14, 'Celeritas'),
|
||||
new Hero(15, 'Magneta'),
|
||||
new Hero(16, 'RubberMan')
|
||||
];
|
||||
|
||||
var heroesPromise = Promise.resolve(HEROES);
|
|
@ -0,0 +1,23 @@
|
|||
/* First version */
|
||||
// #docplaster
|
||||
|
||||
// #docregion all
|
||||
import {AppComponent} from './app.component';
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
|
||||
// #enddocregion all
|
||||
|
||||
/* Can't use AppComponent ... but display as if we can
|
||||
// #docregion all
|
||||
bootstrap(AppComponent, [
|
||||
// #enddocregion all
|
||||
*/
|
||||
|
||||
// Actually use the v.1 component
|
||||
import {AppComponent as ac} from './app.component.1';
|
||||
bootstrap(ac, [
|
||||
// #docregion all
|
||||
ROUTER_PROVIDERS
|
||||
]);
|
||||
// #enddocregion all
|
|
@ -0,0 +1,32 @@
|
|||
/* Second version */
|
||||
// For Milestone #2
|
||||
// Also includes digression on HashPathStrategy (not used in the final app)
|
||||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
import {AppComponent} from './app.component';
|
||||
|
||||
// Add these symbols to override the `LocationStrategy`
|
||||
import {provide} from '@angular/core';
|
||||
import {LocationStrategy,
|
||||
HashLocationStrategy} from '@angular/common';
|
||||
// #enddocregion
|
||||
/* Can't use AppComponent ... but display as if we can
|
||||
// #docregion
|
||||
|
||||
bootstrap(AppComponent, [
|
||||
// #enddocregion
|
||||
*/
|
||||
|
||||
// Actually use the v.2 component
|
||||
import {AppComponent as ac} from './app.component.2';
|
||||
|
||||
bootstrap(ac, [
|
||||
// #docregion
|
||||
ROUTER_PROVIDERS,
|
||||
provide(LocationStrategy,
|
||||
{useClass: HashLocationStrategy}) // .../#/crisis-center/
|
||||
]);
|
||||
// #enddocregion
|
|
@ -0,0 +1,7 @@
|
|||
// #docregion
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
|
||||
import {AppComponent} from './app.component.3';
|
||||
|
||||
bootstrap(AppComponent, [ROUTER_PROVIDERS]);
|
|
@ -0,0 +1,7 @@
|
|||
// #docregion
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
|
||||
import {AppComponent} from './app.component';
|
||||
|
||||
bootstrap(AppComponent, [ROUTER_PROVIDERS]);
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<!-- #docregion base-href -->
|
||||
<base href="/">
|
||||
<!-- #enddocregion base-href -->
|
||||
<title>Router Sample v.1</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app/main.1') // <----- ONLY CHANGE
|
||||
.then(null, console.error.bind(console));
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Milestone 1</h1>
|
||||
<my-app>loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Router Sample v.2</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app/main.2') // <----- ONLY CHANGE
|
||||
.then(null, console.error.bind(console));
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Milestone 2</h1>
|
||||
<my-app>loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<base href="/">
|
||||
<title>Router Sample v.3</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app/main.3') // <----- ONLY CHANGE
|
||||
.then(null, console.error.bind(console));
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Milestone 3</h1>
|
||||
<my-app>loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<!-- Set the base href -->
|
||||
<base href="/">
|
||||
<title>Router Sample</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
|
||||
|
||||
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
<script src="systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('app').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<my-app>loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
|
@ -3,12 +3,10 @@
|
|||
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion import-router
|
||||
import { RouteConfig, ROUTER_DIRECTIVES } from '@angular/router-deprecated';
|
||||
// #enddocregion import-router
|
||||
import { Routes, ROUTER_DIRECTIVES } from '@angular/router';
|
||||
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
|
@ -16,8 +14,8 @@ import { HeroListComponent } from './hero-list.component';
|
|||
template: `
|
||||
<h1>Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
<a [routerLink]="['/crisis-center']">Crisis Center</a>
|
||||
<a [routerLink]="['/heroes']">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
|
@ -26,16 +24,17 @@ import { HeroListComponent } from './hero-list.component';
|
|||
})
|
||||
// #enddocregion
|
||||
/*
|
||||
// #docregion route-config
|
||||
@Component({ ... })
|
||||
// #enddocregion route-config
|
||||
*/
|
||||
// #docregion route-config
|
||||
@Component({ ... })
|
||||
// #enddocregion route-config
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
@Routes([
|
||||
// #docregion route-defs
|
||||
{path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent},
|
||||
{path: '/heroes', name: 'Heroes', component: HeroListComponent}
|
||||
{path: '/crisis-center', component: CrisisListComponent},
|
||||
{path: '/heroes', component: HeroListComponent},
|
||||
{path: '*', component: CrisisListComponent}
|
||||
// #enddocregion route-defs
|
||||
])
|
||||
export class AppComponent { }
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Routes, ROUTER_DIRECTIVES, Router } from '@angular/router';
|
||||
|
||||
import {CrisisListComponent} from './crisis-list.component';
|
||||
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
|
||||
*/
|
||||
// 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';
|
||||
import { HeroListComponent } from './heroes/hero-list.component.1';
|
||||
import { HeroDetailComponent } from './heroes/hero-detail.component.1';
|
||||
import { HeroService } from './heroes/hero.service';
|
||||
// #docregion
|
||||
|
||||
@Component({
|
||||
|
@ -28,8 +28,8 @@ import {HeroService} from './heroes/hero.service';
|
|||
template: `
|
||||
<h1>Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
<a [routerLink]="['/crisis-center']">Crisis Center</a>
|
||||
<a [routerLink]="['/heroes']">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
|
@ -38,21 +38,27 @@ import {HeroService} from './heroes/hero.service';
|
|||
})
|
||||
// #enddocregion
|
||||
/*
|
||||
// #docregion route-config
|
||||
@Component({ ... })
|
||||
// #enddocregion route-config
|
||||
*/
|
||||
// #docregion route-config
|
||||
@Component({ ... })
|
||||
// #enddocregion route-config
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
@Routes([
|
||||
// #docregion route-defs
|
||||
{path: '/crisis-center', name: 'CrisisCenter', component: CrisisListComponent},
|
||||
{path: '/heroes', name: 'Heroes', component: HeroListComponent},
|
||||
{path: '/crisis-center', component: CrisisListComponent},
|
||||
{path: '/heroes', component: HeroListComponent},
|
||||
// #docregion hero-detail-route
|
||||
{path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent}
|
||||
{path: '/hero/:id', component: HeroDetailComponent}
|
||||
// #enddocregion hero-detail-route
|
||||
// #enddocregion route-defs
|
||||
])
|
||||
export class AppComponent { }
|
||||
export class AppComponent implements OnInit {
|
||||
constructor(private router: Router) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.router.navigate(['/crisis-center']);
|
||||
}
|
||||
}
|
||||
// #enddocregion route-config
|
||||
// #enddocregion
|
||||
|
|
|
@ -1,45 +1,48 @@
|
|||
/* tslint:disable:no-unused-variable */
|
||||
// #docplaster
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Routes, ROUTER_DIRECTIVES, Router } from '@angular/router';
|
||||
|
||||
import {CrisisCenterComponent} from './crisis-center/crisis-center.component.1';
|
||||
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';
|
||||
import { DialogService } from './dialog.service';
|
||||
import { HeroService } from './heroes/hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
// #enddocregion
|
||||
/* Typical link
|
||||
// #docregion h-anchor
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
// #enddocregion h-anchor
|
||||
*/
|
||||
// #docregion h-anchor
|
||||
<a [routerLink]="['/heroes']">Heroes</a>
|
||||
// #enddocregion h-anchor
|
||||
*/
|
||||
/* Incomplete Crisis Center link when CC lacks a default
|
||||
// #docregion cc-anchor-fail
|
||||
// The link now fails with a "non-terminal link" error
|
||||
// #docregion cc-anchor-w-default
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
// #enddocregion cc-anchor-w-default
|
||||
// #enddocregion cc-anchor-fail
|
||||
*/
|
||||
// #docregion cc-anchor-fail
|
||||
// The link now fails with a "non-terminal link" error
|
||||
// #docregion cc-anchor-w-default
|
||||
<a [routerLink]="['/crisis-center']">Crisis Center</a>
|
||||
// #enddocregion cc-anchor-w-default
|
||||
// #enddocregion cc-anchor-fail
|
||||
*/
|
||||
/* Crisis Center link when CC lacks a default
|
||||
// #docregion cc-anchor-no-default
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisList']">Crisis Center</a>
|
||||
// #enddocregion cc-anchor-no-default
|
||||
*/
|
||||
// #docregion cc-anchor-no-default
|
||||
<a [routerLink]="['/crisis-center/']">Crisis Center</a>
|
||||
// #enddocregion cc-anchor-no-default
|
||||
*/
|
||||
/* Crisis Center Detail link
|
||||
// #docregion Dragon-anchor
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisDetail', {id:1}]">Dragon Crisis</a>
|
||||
// #enddocregion Dragon-anchor
|
||||
*/
|
||||
// #docregion Dragon-anchor
|
||||
<a [routerLink]="['/crisis-center/1']">Dragon Crisis</a>
|
||||
// #enddocregion Dragon-anchor
|
||||
*/
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1 class="title">Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisList']">Crisis Center</a>
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisDetail', {id:1}]">Dragon Crisis</a>
|
||||
<a [routerLink]="['CrisisCenter', 'CrisisDetail', {id:2}]">Shark Crisis</a>
|
||||
<a [routerLink]="['/crisis-center']">Crisis Center</a>
|
||||
<a [routerLink]="['/crisis-center', 1]">Dragon Crisis</a>
|
||||
<a [routerLink]="['/crisis-center', 2]">Shark Crisis</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
|
@ -47,7 +50,14 @@ import {HeroService} from './heroes/hero.service';
|
|||
providers: [DialogService, HeroService],
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
@RouteConfig([
|
||||
{path: '/crisis-center/...', name: 'CrisisCenter', component: CrisisCenterComponent},
|
||||
@Routes([
|
||||
{path: '/crisis-center', component: CrisisCenterComponent},
|
||||
{path: '*', component: CrisisCenterComponent}
|
||||
])
|
||||
export class AppComponent { }
|
||||
export class AppComponent implements OnInit {
|
||||
constructor(private router: Router) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.router.navigate(['/crisis-center']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/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';
|
||||
import { HeroListComponent } from './heroes/hero-list.component';
|
||||
import { HeroDetailComponent } from './heroes/hero-detail.component';
|
||||
|
||||
import {DialogService} from './dialog.service';
|
||||
import {HeroService} from './heroes/hero.service';
|
||||
import { DialogService } from './dialog.service';
|
||||
import { HeroService } from './heroes/hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
|
@ -16,8 +16,8 @@ import {HeroService} from './heroes/hero.service';
|
|||
template: `
|
||||
<h1 class="title">Component Router</h1>
|
||||
<nav>
|
||||
<a [routerLink]="['CrisisCenter']">Crisis Center</a>
|
||||
<a [routerLink]="['Heroes']">Heroes</a>
|
||||
<a [routerLink]="['/crisis-center']">Crisis Center</a>
|
||||
<a [routerLink]="['/heroes']">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
|
@ -25,20 +25,17 @@ import {HeroService} from './heroes/hero.service';
|
|||
providers: [DialogService, HeroService],
|
||||
directives: [ROUTER_DIRECTIVES]
|
||||
})
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
|
||||
// #docregion route-config-cc
|
||||
{ // Crisis Center child route
|
||||
path: '/crisis-center/...',
|
||||
name: 'CrisisCenter',
|
||||
component: CrisisCenterComponent,
|
||||
useAsDefault: true
|
||||
},
|
||||
// #enddocregion route-config-cc
|
||||
|
||||
{path: '/heroes', name: 'Heroes', component: HeroListComponent},
|
||||
{path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent},
|
||||
// #docregion routes
|
||||
@Routes([
|
||||
{path: '/crisis-center', component: CrisisCenterComponent},
|
||||
{path: '/heroes', component: HeroListComponent},
|
||||
{path: '/hero/:id', component: HeroDetailComponent},
|
||||
])
|
||||
// #enddocregion route-config
|
||||
export class AppComponent { }
|
||||
// #enddocregion routes
|
||||
export class AppComponent implements OnInit {
|
||||
constructor(private router: Router) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.router.navigate(['/crisis-center']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, RouterOutlet} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Routes, ROUTER_DIRECTIVES } from '@angular/router';
|
||||
|
||||
import {CrisisListComponent} from './crisis-list.component.1';
|
||||
import {CrisisDetailComponent} from './crisis-detail.component.1';
|
||||
import {CrisisService} from './crisis.service';
|
||||
import { CrisisListComponent } from './crisis-list.component.1';
|
||||
import { CrisisDetailComponent } from './crisis-detail.component.1';
|
||||
import { CrisisService } from './crisis.service';
|
||||
|
||||
// #docregion minus-imports
|
||||
@Component({
|
||||
|
@ -11,17 +11,17 @@ import {CrisisService} from './crisis.service';
|
|||
<h2>CRISIS CENTER</h2>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
directives: [RouterOutlet],
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
// #docregion providers
|
||||
providers: [CrisisService]
|
||||
// #enddocregion providers
|
||||
})
|
||||
// #docregion route-config
|
||||
@RouteConfig([
|
||||
@Routes([
|
||||
// #docregion default-route
|
||||
{path:'/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true},
|
||||
{path: '/', component: CrisisListComponent}, // , useAsDefault: true}, // coming soon
|
||||
// #enddocregion default-route
|
||||
{path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
|
||||
{path: '/:id', component: CrisisDetailComponent}
|
||||
])
|
||||
// #enddocregion route-config
|
||||
export class CrisisCenterComponent { }
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import {RouteConfig, RouterOutlet} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Routes, ROUTER_DIRECTIVES } from '@angular/router';
|
||||
|
||||
import {CrisisListComponent} from './crisis-list.component';
|
||||
import {CrisisDetailComponent} from './crisis-detail.component';
|
||||
import {CrisisService} from './crisis.service';
|
||||
import { CrisisListComponent } from './crisis-list.component';
|
||||
import { CrisisDetailComponent } from './crisis-detail.component';
|
||||
import { CrisisService } from './crisis.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<h2>CRISIS CENTER</h2>
|
||||
<router-outlet></router-outlet>
|
||||
`,
|
||||
directives: [RouterOutlet],
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
providers: [CrisisService]
|
||||
})
|
||||
@RouteConfig([
|
||||
{path:'/', name: 'CrisisList', component: CrisisListComponent, useAsDefault: true},
|
||||
{path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
|
||||
@Routes([
|
||||
{path: '', component: CrisisListComponent}, // , useAsDefault: true}, // coming soon
|
||||
{path: '/:id', component: CrisisDetailComponent}
|
||||
])
|
||||
export class CrisisCenterComponent { }
|
||||
// #enddocregion
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Crisis, CrisisService } from './crisis.service';
|
||||
import { Router, OnActivate, RouteSegment } from '@angular/router';
|
||||
// #docregion routerCanDeactivate
|
||||
import {CanDeactivate, ComponentInstruction} from '@angular/router-deprecated';
|
||||
import {DialogService} from '../dialog.service';
|
||||
// import { CanDeactivate } from '@angular/router';
|
||||
import { DialogService } from '../dialog.service';
|
||||
|
||||
// #enddocregion routerCanDeactivate
|
||||
|
||||
@Component({
|
||||
// #docregion template
|
||||
template: `
|
||||
|
@ -31,23 +29,22 @@ import {DialogService} from '../dialog.service';
|
|||
styles: ['input {width: 20em}']
|
||||
})
|
||||
// #docregion routerCanDeactivate, cancel-save
|
||||
export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
||||
export class CrisisDetailComponent implements OnActivate {// , CanDeactivate {
|
||||
|
||||
crisis: Crisis;
|
||||
editName: string;
|
||||
|
||||
// #enddocregion routerCanDeactivate, cancel-save
|
||||
constructor(
|
||||
private _service: CrisisService,
|
||||
private _router: Router,
|
||||
private _routeParams: RouteParams,
|
||||
private _dialog: DialogService
|
||||
private service: CrisisService,
|
||||
private router: Router,
|
||||
private dialog: DialogService
|
||||
) { }
|
||||
|
||||
// #docregion ngOnInit
|
||||
ngOnInit() {
|
||||
let id = +this._routeParams.get('id');
|
||||
this._service.getCrisis(id).then(crisis => {
|
||||
// #docregion ngOnActivate
|
||||
routerOnActivate(curr: RouteSegment): void {
|
||||
let id = +curr.getParam('id');
|
||||
this.service.getCrisis(id).then(crisis => {
|
||||
if (crisis) {
|
||||
this.editName = crisis.name;
|
||||
this.crisis = crisis;
|
||||
|
@ -56,17 +53,18 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
|||
}
|
||||
});
|
||||
}
|
||||
// #enddocregion ngOnInit
|
||||
// #enddocregion ngOnActivate
|
||||
|
||||
// #docregion routerCanDeactivate
|
||||
routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any {
|
||||
// NOT IMPLEMENTED YET
|
||||
routerCanDeactivate(): 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?');
|
||||
return this.dialog.confirm('Discard changes?');
|
||||
}
|
||||
// #enddocregion routerCanDeactivate
|
||||
|
||||
|
@ -84,8 +82,8 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
|||
|
||||
// #docregion gotoCrises
|
||||
gotoCrises() {
|
||||
// Like <a [routerLink]="['CrisisList']">Crisis Center</a
|
||||
this._router.navigate(['CrisisList']);
|
||||
// Like <a [routerLink]="[/crisis-center/]">Crisis Center</a
|
||||
this.router.navigateByUrl('/crisis-center/'); // absolute url
|
||||
}
|
||||
// #enddocregion gotoCrises
|
||||
// #docregion routerCanDeactivate, cancel-save
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
import {CanDeactivate, ComponentInstruction} from '@angular/router-deprecated';
|
||||
import {DialogService} from '../dialog.service';
|
||||
import { Component } from '@angular/core';
|
||||
import { Crisis, CrisisService } from './crisis.service';
|
||||
import { Router, OnActivate, CanDeactivate, RouteSegment } from '@angular/router';
|
||||
import { DialogService } from '../dialog.service';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
@ -26,21 +24,22 @@ import {DialogService} from '../dialog.service';
|
|||
styles: ['input {width: 20em}']
|
||||
})
|
||||
|
||||
export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
||||
|
||||
export class CrisisDetailComponent implements OnActivate, CanDeactivate {
|
||||
crisis: Crisis;
|
||||
editName: string;
|
||||
private curSegment: RouteSegment;
|
||||
|
||||
constructor(
|
||||
private _service: CrisisService,
|
||||
private _router: Router,
|
||||
private _routeParams: RouteParams,
|
||||
private _dialog: DialogService
|
||||
private service: CrisisService,
|
||||
private router: Router,
|
||||
private dialog: DialogService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
let id = +this._routeParams.get('id');
|
||||
this._service.getCrisis(id).then(crisis => {
|
||||
routerOnActivate(curr: RouteSegment) {
|
||||
this.curSegment = curr;
|
||||
|
||||
let id = +curr.getParam('id');
|
||||
this.service.getCrisis(id).then(crisis => {
|
||||
if (crisis) {
|
||||
this.editName = crisis.name;
|
||||
this.crisis = crisis;
|
||||
|
@ -50,18 +49,17 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
|||
});
|
||||
}
|
||||
|
||||
routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any {
|
||||
routerCanDeactivate(): 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?');
|
||||
return this.dialog.confirm('Discard changes?');
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.editName = this.crisis.name;
|
||||
this.gotoCrises();
|
||||
}
|
||||
|
||||
|
@ -77,7 +75,11 @@ export class CrisisDetailComponent implements OnInit, CanDeactivate {
|
|||
// so that the CrisisListComponent can select that hero.
|
||||
// Add a totally useless `foo` parameter for kicks.
|
||||
// #docregion gotoCrises-navigate
|
||||
this._router.navigate(['CrisisList', {id: crisisId, foo: 'foo'} ]);
|
||||
// Absolute link
|
||||
this.router.navigate(['/crisis-center', {id: crisisId, foo: 'foo'}]);
|
||||
|
||||
// Relative link
|
||||
// this.router.navigate(['../', {id: crisisId, foo: 'foo'}], this.curSegment);
|
||||
// #enddocregion gotoCrises-navigate
|
||||
}
|
||||
// #enddocregion gotoCrises
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {Router} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Crisis, CrisisService } from './crisis.service';
|
||||
import { Router, OnActivate, RouteSegment } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
// #docregion template
|
||||
|
@ -17,20 +16,20 @@ import {Router} from '@angular/router-deprecated';
|
|||
`,
|
||||
// #enddocregion template
|
||||
})
|
||||
export class CrisisListComponent implements OnInit {
|
||||
export class CrisisListComponent implements OnActivate {
|
||||
crises: Crisis[];
|
||||
|
||||
constructor(
|
||||
private _service: CrisisService,
|
||||
private _router: Router) {}
|
||||
private service: CrisisService,
|
||||
private router: Router) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._service.getCrises().then(crises => this.crises = crises);
|
||||
routerOnActivate(curr: RouteSegment): void {
|
||||
this.service.getCrises().then(crises => this.crises = crises);
|
||||
}
|
||||
|
||||
// #docregion select
|
||||
onSelect(crisis: Crisis) {
|
||||
this._router.navigate(['CrisisDetail', { id: crisis.id }] );
|
||||
this.router.navigateByUrl( `/crisis-list/${crisis.id}`);
|
||||
}
|
||||
// #enddocregion select
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Crisis, CrisisService} from './crisis.service';
|
||||
import {Router, RouteParams} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Crisis, CrisisService } from './crisis.service';
|
||||
import { Router, OnActivate, RouteSegment, RouteTree } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
@ -16,25 +15,28 @@ import {Router, RouteParams} from '@angular/router-deprecated';
|
|||
</ul>
|
||||
`,
|
||||
})
|
||||
export class CrisisListComponent implements OnInit {
|
||||
export class CrisisListComponent implements OnActivate {
|
||||
crises: Crisis[];
|
||||
|
||||
private _selectedId: number;
|
||||
private currSegment: RouteSegment;
|
||||
private selectedId: number;
|
||||
|
||||
constructor(
|
||||
private _service: CrisisService,
|
||||
private _router: Router,
|
||||
routeParams: RouteParams) {
|
||||
this._selectedId = +routeParams.get('id');
|
||||
}
|
||||
private service: CrisisService,
|
||||
private router: Router) { }
|
||||
|
||||
isSelected(crisis: Crisis) { return crisis.id === this._selectedId; }
|
||||
isSelected(crisis: Crisis) { return crisis.id === this.selectedId; }
|
||||
|
||||
ngOnInit() {
|
||||
this._service.getCrises().then(crises => this.crises = crises);
|
||||
routerOnActivate(curr: RouteSegment, prev: RouteSegment, currTree: RouteTree) {
|
||||
this.currSegment = curr;
|
||||
this.selectedId = +currTree.parent(curr).getParam('id');
|
||||
this.service.getCrises().then(crises => this.crises = crises);
|
||||
}
|
||||
|
||||
onSelect(crisis: Crisis) {
|
||||
this._router.navigate( ['CrisisDetail', { id: crisis.id }] );
|
||||
// Absolute link
|
||||
// this.router.navigate([`/crisis-center`, crisis.id]);
|
||||
|
||||
// Relative link
|
||||
this.router.navigate([`./${crisis.id}`], this.currSegment);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
export class Crisis {
|
||||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
const CRISES = [
|
||||
new Crisis(1, 'Dragon Burning Cities'),
|
||||
new Crisis(2, 'Sky Rains Great White Sharks'),
|
||||
new Crisis(3, 'Giant Asteroid Heading For Earth'),
|
||||
new Crisis(4, 'Procrastinators Meeting Delayed Again'),
|
||||
];
|
||||
|
||||
let crisesPromise = Promise.resolve(CRISES);
|
||||
|
||||
// #docregion
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class CrisisService {
|
||||
|
||||
static nextCrisisId = 100;
|
||||
|
||||
getCrises() { return crisesPromise; }
|
||||
|
||||
getCrisis(id: number | string) {
|
||||
|
@ -18,24 +30,13 @@ export class CrisisService {
|
|||
|
||||
// #enddocregion
|
||||
|
||||
static nextCrisisId = 100;
|
||||
|
||||
addCrisis(name:string) {
|
||||
addCrisis(name: string) {
|
||||
name = name.trim();
|
||||
if (name){
|
||||
if (name) {
|
||||
let crisis = new Crisis(CrisisService.nextCrisisId++, name);
|
||||
crisesPromise.then(crises => crises.push(crisis));
|
||||
}
|
||||
}
|
||||
// #docregion
|
||||
}
|
||||
|
||||
var crises = [
|
||||
new Crisis(1, 'Dragon Burning Cities'),
|
||||
new Crisis(2, 'Sky Rains Great White Sharks'),
|
||||
new Crisis(3, 'Giant Asteroid Heading For Earth'),
|
||||
new Crisis(4, 'Procrastinators Meeting Delayed Again'),
|
||||
];
|
||||
|
||||
var crisesPromise = Promise.resolve(crises);
|
||||
// #enddocregion
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Initial empty version
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// #docregion
|
||||
import {Injectable} from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
/**
|
||||
* Async modal dialog service
|
||||
* DialogService makes this app easier to test by faking this service.
|
||||
|
@ -11,7 +11,7 @@ export class DialogService {
|
|||
* Ask user to confirm an action. `message` explains the action and choices.
|
||||
* Returns promise resolving to `true`=confirm or `false`=cancel
|
||||
*/
|
||||
confirm(message?:string) {
|
||||
confirm(message?: string) {
|
||||
return new Promise<boolean>((resolve, reject) =>
|
||||
resolve(window.confirm(message || 'Is it OK?')));
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/// Initial empty version
|
||||
// #docregion
|
||||
import {Component} from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Hero, HeroService } from './hero.service';
|
||||
import { Router, OnActivate, RouteSegment } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
@ -20,27 +20,26 @@ import {RouteParams, Router} from '@angular/router-deprecated';
|
|||
</div>
|
||||
`,
|
||||
})
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
export class HeroDetailComponent implements OnActivate {
|
||||
hero: Hero;
|
||||
|
||||
// #docregion ctor
|
||||
constructor(
|
||||
private _router:Router,
|
||||
private _routeParams:RouteParams,
|
||||
private _service:HeroService){}
|
||||
private router: Router,
|
||||
private service: HeroService) {}
|
||||
// #enddocregion ctor
|
||||
|
||||
// #docregion ngOnInit
|
||||
ngOnInit() {
|
||||
let id = this._routeParams.get('id');
|
||||
this._service.getHero(id).then(hero => this.hero = hero);
|
||||
// #docregion OnActivate
|
||||
routerOnActivate(curr: RouteSegment): void {
|
||||
let id = +curr.getParam('id');
|
||||
this.service.getHero(id).then(hero => this.hero = hero);
|
||||
}
|
||||
// #enddocregion ngOnInit
|
||||
// #enddocregion OnActivate
|
||||
|
||||
// #docregion gotoHeroes
|
||||
gotoHeroes() {
|
||||
// Like <a [routerLink]="['Heroes']">Heroes</a>
|
||||
this._router.navigate(['Heroes']);
|
||||
// Like <a [routerLink]="['/heroes']">Heroes</a>
|
||||
this.router.navigate(['/heroes']);
|
||||
}
|
||||
// #enddocregion gotoHeroes
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
import {RouteParams, Router} from '@angular/router-deprecated';
|
||||
import { Component } from '@angular/core';
|
||||
import { Hero, HeroService } from './hero.service';
|
||||
import { Router, OnActivate, RouteSegment } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
|
@ -20,32 +20,30 @@ import {RouteParams, Router} from '@angular/router-deprecated';
|
|||
</div>
|
||||
`,
|
||||
})
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
export class HeroDetailComponent implements OnActivate {
|
||||
hero: Hero;
|
||||
|
||||
// #docregion ctor
|
||||
constructor(
|
||||
private _router:Router,
|
||||
private _routeParams:RouteParams,
|
||||
private _service:HeroService){}
|
||||
private router: Router,
|
||||
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
|
||||
// #docregion OnActivate
|
||||
routerOnActivate(curr: RouteSegment): void {
|
||||
let id = +curr.getParam('id');
|
||||
this.service.getHero(id).then(hero => this.hero = hero);
|
||||
}
|
||||
// #enddocregion OnActivate
|
||||
|
||||
gotoHeroes() {
|
||||
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'} ]);
|
||||
this.router.navigate([`/heroes`, {id: heroId, foo: 'foo'}]);
|
||||
// #enddocregion gotoHeroes-navigate
|
||||
}
|
||||
// #enddocregion gotoHeroes
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
// TODO SOMEDAY: Feature Componetized like HeroCenter
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
|
@ -24,18 +23,18 @@ export class HeroListComponent implements OnInit {
|
|||
|
||||
// #docregion ctor
|
||||
constructor(
|
||||
private _router: Router,
|
||||
private _service: HeroService) { }
|
||||
private router: Router,
|
||||
private service: HeroService) { }
|
||||
// #enddocregion ctor
|
||||
|
||||
ngOnInit() {
|
||||
this._service.getHeroes().then(heroes => this.heroes = heroes)
|
||||
this.service.getHeroes().then(heroes => this.heroes = heroes)
|
||||
}
|
||||
|
||||
// #docregion select
|
||||
onSelect(hero: Hero) {
|
||||
// #docregion nav-to-detail
|
||||
this._router.navigate( ['HeroDetail', { id: hero.id }] );
|
||||
this.router.navigate(['/hero', hero.id]);
|
||||
// #enddocregion nav-to-detail
|
||||
}
|
||||
// #enddocregion select
|
||||
|
@ -43,7 +42,7 @@ export class HeroListComponent implements OnInit {
|
|||
// #enddocregion
|
||||
|
||||
/* A link parameters array
|
||||
// #docregion link-parameters-array
|
||||
['HeroDetail', { id: hero.id }] // {id: 15}
|
||||
// #enddocregion link-parameters-array
|
||||
*/
|
||||
// #docregion link-parameters-array
|
||||
['HeroDetail', { id: hero.id }] // {id: 15}
|
||||
// #enddocregion link-parameters-array
|
||||
*/
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// #docplaster
|
||||
|
||||
// TODO SOMEDAY: Feature Componetized like CrisisCenter
|
||||
// #docregion
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Hero, HeroService} from './hero.service';
|
||||
// TODO SOMEDAY: Feature Componetized like CrisisCenter
|
||||
import { Component } from '@angular/core';
|
||||
import { Hero, HeroService} from './hero.service';
|
||||
// #docregion import-route-params
|
||||
import {Router, RouteParams} from '@angular/router-deprecated';
|
||||
import { Router, RouteSegment, Tree, OnActivate, RouteTree } from '@angular/router';
|
||||
// #enddocregion import-route-params
|
||||
|
||||
@Component({
|
||||
|
@ -22,32 +21,31 @@ import {Router, RouteParams} from '@angular/router-deprecated';
|
|||
`
|
||||
// #enddocregion template
|
||||
})
|
||||
export class HeroListComponent implements OnInit {
|
||||
export class HeroListComponent implements OnActivate {
|
||||
heroes: Hero[];
|
||||
|
||||
// #docregion ctor
|
||||
private _selectedId: number;
|
||||
private selectedId: number;
|
||||
|
||||
constructor(
|
||||
private _service: HeroService,
|
||||
private _router: Router,
|
||||
routeParams: RouteParams) {
|
||||
this._selectedId = +routeParams.get('id');
|
||||
}
|
||||
private service: HeroService,
|
||||
private router: Router) { }
|
||||
// #enddocregion ctor
|
||||
|
||||
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: RouteTree, prevTree?: RouteTree): void {
|
||||
this.selectedId = +curr.getParam('id');
|
||||
this.service.getHeroes().then(heroes => this.heroes = heroes);
|
||||
}
|
||||
|
||||
// #docregion isSelected
|
||||
isSelected(hero: Hero) { return hero.id === this._selectedId; }
|
||||
isSelected(hero: Hero) { return hero.id === this.selectedId; }
|
||||
// #enddocregion isSelected
|
||||
|
||||
// #docregion select
|
||||
onSelect(hero: Hero) {
|
||||
this._router.navigate( ['HeroDetail', { id: hero.id }] );
|
||||
this.router.navigate(['/hero', hero.id]);
|
||||
}
|
||||
// #enddocregion select
|
||||
|
||||
ngOnInit() {
|
||||
this._service.getHeroes().then(heroes => this.heroes = heroes)
|
||||
}
|
||||
}
|
||||
// #enddocregion
|
||||
|
|
|
@ -5,6 +5,17 @@ export class Hero {
|
|||
constructor(public id: number, public name: string) { }
|
||||
}
|
||||
|
||||
let HEROES = [
|
||||
new Hero(11, 'Mr. Nice'),
|
||||
new Hero(12, 'Narco'),
|
||||
new Hero(13, 'Bombasto'),
|
||||
new Hero(14, 'Celeritas'),
|
||||
new Hero(15, 'Magneta'),
|
||||
new Hero(16, 'RubberMan')
|
||||
];
|
||||
|
||||
let heroesPromise = Promise.resolve(HEROES);
|
||||
|
||||
@Injectable()
|
||||
export class HeroService {
|
||||
getHeroes() { return heroesPromise; }
|
||||
|
@ -14,14 +25,3 @@ export class HeroService {
|
|||
.then(heroes => heroes.filter(h => h.id === +id)[0]);
|
||||
}
|
||||
}
|
||||
|
||||
var HEROES = [
|
||||
new Hero(11, 'Mr. Nice'),
|
||||
new Hero(12, 'Narco'),
|
||||
new Hero(13, 'Bombasto'),
|
||||
new Hero(14, 'Celeritas'),
|
||||
new Hero(15, 'Magneta'),
|
||||
new Hero(16, 'RubberMan')
|
||||
];
|
||||
|
||||
var heroesPromise = Promise.resolve(HEROES);
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion all
|
||||
import {AppComponent} from './app.component';
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { ROUTER_PROVIDERS } from '@angular/router';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
// #enddocregion all
|
||||
|
||||
/* Can't use AppComponent ... but display as if we can
|
||||
|
@ -15,9 +15,9 @@ bootstrap(AppComponent, [
|
|||
*/
|
||||
|
||||
// Actually use the v.1 component
|
||||
import {AppComponent as ac} from './app.component.1';
|
||||
import { AppComponent as ac } from './app.component.1';
|
||||
bootstrap(ac, [
|
||||
// #docregion all
|
||||
ROUTER_PROVIDERS
|
||||
]);
|
||||
// #enddocregion all
|
||||
// #enddocregion all
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
// #docplaster
|
||||
|
||||
// #docregion
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
import {AppComponent} from './app.component';
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { ROUTER_PROVIDERS } from '@angular/router';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
// Add these symbols to override the `LocationStrategy`
|
||||
import {provide} from '@angular/core';
|
||||
import {LocationStrategy,
|
||||
HashLocationStrategy} from '@angular/common';
|
||||
import { provide } from '@angular/core';
|
||||
import { LocationStrategy,
|
||||
HashLocationStrategy } from '@angular/common';
|
||||
// #enddocregion
|
||||
/* Can't use AppComponent ... but display as if we can
|
||||
// #docregion
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// #docregion
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { ROUTER_PROVIDERS } from '@angular/router';
|
||||
|
||||
import {AppComponent} from './app.component.3';
|
||||
import { AppComponent } from './app.component.3';
|
||||
|
||||
bootstrap(AppComponent, [ROUTER_PROVIDERS]);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// #docregion
|
||||
import {bootstrap} from '@angular/platform-browser-dynamic';
|
||||
import {ROUTER_PROVIDERS} from '@angular/router-deprecated';
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { ROUTER_PROVIDERS } from '@angular/router';
|
||||
|
||||
import {AppComponent} from './app.component';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
bootstrap(AppComponent, [ROUTER_PROVIDERS]);
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<!-- #docregion base-href -->
|
||||
<base href="/">
|
||||
<!-- #enddocregion base-href -->
|
||||
<title>Router Sample v.2</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
@ -29,5 +27,10 @@
|
|||
<my-app>loading...</my-app>
|
||||
</body>
|
||||
|
||||
<body>
|
||||
<h1>Milestone 2</h1>
|
||||
<my-app>loading...</my-app>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- #enddocregion -->
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
<!-- #docregion -->
|
||||
<html>
|
||||
<head>
|
||||
<!-- #docregion base-href -->
|
||||
<base href="/">
|
||||
<!-- #enddocregion base-href -->
|
||||
<title>Router Sample v.4</title>
|
||||
<title>Router Sample v.3</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- #docregion -->
|
||||
<html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Set the base href -->
|
||||
<!-- #docregion base-href -->
|
||||
<base href="/">
|
||||
<!-- #enddocregion base-href -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Router Sample</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
'@angular/http',
|
||||
'@angular/platform-browser',
|
||||
'@angular/platform-browser-dynamic',
|
||||
'@angular/router',
|
||||
'@angular/router-deprecated',
|
||||
'@angular/testing',
|
||||
'@angular/upgrade',
|
||||
];
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
'@angular/http',
|
||||
'@angular/platform-browser',
|
||||
'@angular/platform-browser-dynamic',
|
||||
'@angular/router',
|
||||
'@angular/router-deprecated',
|
||||
'@angular/testing',
|
||||
'@angular/upgrade',
|
||||
];
|
||||
|
||||
|
|
|
@ -100,9 +100,15 @@
|
|||
"intro": "Pipes transform displayed values within a template."
|
||||
},
|
||||
|
||||
"router-deprecated": {
|
||||
"title": "Beta Router (Deprecated)",
|
||||
"intro": "The deprecated Beta Router."
|
||||
},
|
||||
|
||||
"router": {
|
||||
"title": "Routing & Navigation",
|
||||
"intro": "Discover the basics of screen navigation with the Angular 2 router."
|
||||
"intro": "Discover the basics of screen navigation with the Angular 2 router.",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
"structural-directives": {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
!= partial("../../../_includes/_ts-temp")
|
|
@ -99,9 +99,15 @@
|
|||
"intro": "Pipes transform displayed values within a template."
|
||||
},
|
||||
|
||||
"router-deprecated": {
|
||||
"title": "Beta Router (Deprecated)",
|
||||
"intro": "The deprecated Beta Router."
|
||||
},
|
||||
|
||||
"router": {
|
||||
"title": "Routing & Navigation",
|
||||
"intro": "Discover the basics of screen navigation with the Angular 2 router."
|
||||
"intro": "Discover the basics of screen navigation with the Angular 2 router.",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
"structural-directives": {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
!= partial("../../../_includes/_ts-temp")
|
|
@ -99,9 +99,16 @@
|
|||
"intro": "Pipes transform displayed values within a template."
|
||||
},
|
||||
|
||||
|
||||
"router-deprecated": {
|
||||
"title": "Beta Router (Deprecated)",
|
||||
"intro": "The deprecated Beta Router."
|
||||
},
|
||||
|
||||
"router": {
|
||||
"title": "Routing & Navigation",
|
||||
"intro": "Discover the basics of screen navigation with the Angular 2 router."
|
||||
"intro": "Discover the basics of screen navigation with the Angular 2 Component Router.",
|
||||
"hide": true
|
||||
},
|
||||
|
||||
"structural-directives": {
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
//
|
||||
TODO: REVIVE AUX ROUTE MATERIAL WHEN THAT FEATURE WORKS AS EXPECTED
|
||||
|
||||
PLEASE DO NOT CREATE ISSUES OR PULL REQUESTS FOR THIS PAGE
|
||||
|
||||
<a id="chat-feature"></a>
|
||||
.l-main-section
|
||||
:marked
|
||||
## Milestone #4: Auxiliary Routes
|
||||
Auxiliary routes are routes that can be activated independently of the current
|
||||
route. They are entirely optional, depending on your app needs.
|
||||
|
||||
For example, your application may have a modal that appears and this could
|
||||
be an auxiliary route. The modal may have its own navigation needs, such as a slideshow
|
||||
and that auxiliary route is able to manage the navigation stack independently of the
|
||||
primary routes.
|
||||
|
||||
In our sample application, we also want to have a chat feature that allows people
|
||||
the ability to have a live agent assist them. The chat window will have first an
|
||||
initial route that contains a prompt to ask the visitor if they'd like to chat with
|
||||
an agent. Once they initiate a chat, they go to a new route for the chat experience.
|
||||
|
||||
.alert.is-critical Make diagram of chat routes
|
||||
|
||||
:marked
|
||||
In this auxiliary chat experience, it overlays the current screen and persists.
|
||||
If you navigate from the Heroes to Crisis Center, the chat auxiliary route remains
|
||||
active and in view.
|
||||
|
||||
Therefore the auxiliary routing is truly independent of the other
|
||||
routing. In most respects, an auxiliary route behaves the same outside of it is rendered
|
||||
in its own outlet and modifies the url differently.
|
||||
|
||||
We'll look at how to setup an auxiliary route and considerations for when to use them.
|
||||
|
||||
### Auxiliary Route Outlet
|
||||
In order to get an auxiliary route, it needs a place to be rendered. So far the app has
|
||||
a single `RouterOutet` that the rest of our routes are rendered into. Auxiliary routes need to
|
||||
have their own `RouterOutlet`, and that is done by giving it a name attribute. Open the
|
||||
`app.component.ts` file and let's add the new outlet to the template.
|
||||
.alert.is-critical Should remove app.component.4.ts based example (next) when we know what's what
|
||||
+_makeExample('router/ts/app/app.component.4.ts', 'chat-outlet', 'app/app.component.ts')
|
||||
.alert.is-critical Should be able to project from app.component.ts like this
|
||||
+_makeExample('router/ts/app/app.component.ts', 'template', 'app/app.component.ts (excerpt)')
|
||||
:marked
|
||||
The name of the outlet must be unique to the component. You could reuse the name across
|
||||
different components, so you don't have to worry about collisions.
|
||||
|
||||
Here we give it a name of "chat", which will be used by the router when we setup our
|
||||
route configs. The app component needs to know about this Auxiliary route, so we
|
||||
import the `ChatComponent`, add a new ROUTE_NAME (`chat`),
|
||||
and add a new 'Chat' route to the `ROUTES` in `app.routes.ts` (just below the redirect) .
|
||||
+_makeExample('router/ts/app/routes.ts', null, 'app/routes.ts')
|
||||
:marked
|
||||
Look again at the 'Chat' route
|
||||
+_makeExample('router/ts/app/routes.ts','chat-route')
|
||||
:marked
|
||||
You can see the route definition is nearly the same, except instead of `path` there is
|
||||
an `aux`. The `aux` property makes this an Auxiliary route.
|
||||
|
||||
@TODO Explain how a named outlet is paired with an aux route.
|
||||
|
||||
The chat component defines its own routes just like the other components, even though
|
||||
it is an Auxiliary route.
|
||||
|
||||
+_makeExample('router/ts/app/chat/routes.ts', null, 'app/chat/routes.ts')
|
||||
:marked
|
||||
Even though this is an Auxiliary route, you notice there is no difference in how we've
|
||||
configured the route config for the primary chat component. The chat component also has
|
||||
the `RouterOutlet` Directive in the template so the child components render inside of
|
||||
the chat window.
|
||||
|
||||
In the chat components, we can use `RouterLink` to reference routes just the same as
|
||||
a normal route. Since this is inside of an Auxiliary route, these relative links will
|
||||
resolve within the chat component and not change the primary route (the Crisis Center or
|
||||
Heroes pages).
|
||||
|
||||
+_makeExample('router/ts/app/chat/chat-init.component.ts', 'chat-links')
|
||||
|
||||
:marked
|
||||
When the chat component opens, it first initializes this template to ask the user if
|
||||
they'd like to chat or not. If they agree, it takes them to the chat window where they
|
||||
begin to send messages to the 'live' agent.
|
||||
|
||||
The behavior of the chat components may be interesting, but have no additional insights
|
||||
for routing, except for the ability to deactivate an active Auxiliary route.
|
||||
|
||||
### Exiting an Auxiliary Route
|
||||
|
||||
@TODO Figure out how to close/deactivate an aux route
|
||||
|
||||
### Auxiliary Route URLs
|
||||
|
||||
Auxiliary Routes do modify the url using parens, like so.
|
||||
code-example(format=".", language="bash").
|
||||
localhost:3002/crisis-center(chat)/2(details)
|
||||
:marked
|
||||
This would be the url on a page where the user was viewing an item in the Crisis Center,
|
||||
in this case the "Dragon Burning Cities" crisis, and the `(chat)` Auxiliary Route would
|
||||
active and on the details child route.
|
||||
|
||||
### Multiple Auxiliary Routes
|
||||
|
||||
There is no limit to how many Auxiliary Routes you have defined or active. There is probably
|
||||
a practical limit where too much appears on the screen for a user, but you can have as many
|
||||
Auxiliary Routes as you have named `RouteOutlet`s.
|
||||
|
||||
:marked
|
||||
### Auxiliary Route Summary
|
||||
|
||||
* Auxiliary routes are normal routes that are rendered outside of the primary `RouterOutlet`
|
||||
* They must use a named `RouterOutlet` to render.
|
||||
* Can be activated as long as the parent component is active.
|
||||
* Links inside of child components are resolved against the aux parent component.
|
||||
* Auxiliary routes are deactivated by @TODO?
|
||||
* Routes are indicated in the url using parens.
|
||||
* Multiple aux routes can be active at once.
|
||||
|
||||
### Chat
|
||||
The "Chat" feature area within the `chat` folder looks like this:
|
||||
```
|
||||
app/
|
||||
chat/
|
||||
├── chat-detail.component.ts
|
||||
├── chat-init.component.ts
|
||||
├── chat.component.ts
|
||||
├── chat.service.ts
|
||||
└── routes.ts
|
||||
```
|
||||
+_makeTabs(
|
||||
`router/ts/app/chat/chat.component.ts,
|
||||
router/ts/app/chat/routes.ts,
|
||||
router/ts/app/chat/chat-init.component.ts,
|
||||
router/ts/app/chat/chat-detail.component.ts,
|
||||
router/ts/app/chat/chat.service.ts
|
||||
`,
|
||||
null,
|
||||
`chat.component.ts,
|
||||
chat/routes.ts,
|
||||
chat-init.component.ts,
|
||||
chat-detail.component.ts,
|
||||
chat.service.ts,
|
||||
`)
|
||||
|
||||
|
||||
The following are styles extracted from `styles.css`
|
||||
that only belong if/when we add chat back
|
||||
```
|
||||
/* chat styles */
|
||||
.chat {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 20px;
|
||||
border: 1px solid #1171a3;
|
||||
width: 400px;
|
||||
height: 300px;
|
||||
}
|
||||
.chat h2 {
|
||||
background: #1171a3;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
.chat .close {
|
||||
float: right;
|
||||
display: block;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.chat .chat-content {
|
||||
padding: 10px;
|
||||
}
|
||||
.chat .chat-messages {
|
||||
height: 190px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.chat .chat-input {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.chat .chat-input input {
|
||||
width: 370px;
|
||||
padding: 3px;
|
||||
}
|
||||
```
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,10 @@
|
|||
include ../_util-fns
|
||||
.alert.is-critical
|
||||
:marked
|
||||
This chapter is a *work in progress*.
|
||||
|
||||
It describes the *release candidate* Component Router which
|
||||
replaces the [*beta* router](router-deprecated.html).
|
||||
|
||||
:marked
|
||||
The Angular ***Component Router*** enables navigation from one [view](./glossary.html#view) to the next
|
||||
|
@ -65,7 +71,7 @@ include ../_util-fns
|
|||
|
||||
If the `app` folder is the application root, as it is for our sample application,
|
||||
set the `href` value *exactly* as shown here.
|
||||
+makeExample('router/ts/index.html','base-href', 'index.html (base href)')(format=".")
|
||||
+makeExample('router/ts/index.1.html','base-href', 'index.html (base href)')(format=".")
|
||||
|
||||
:marked
|
||||
### Router imports
|
||||
|
@ -299,7 +305,7 @@ figure.image-display
|
|||
If the `app` folder is the application root, as it is for our application,
|
||||
set the `href` value in **`index.html`** *exactly* as shown here.
|
||||
|
||||
+makeExample('router/ts/index.html','base-href', 'index.html (base href)')(format=".")
|
||||
+makeExample('router/ts/index.1.html','base-href', 'index.html (base href)')(format=".")
|
||||
.l-sub-section
|
||||
:marked
|
||||
HTML 5 style navigation is the Component Router default.
|
||||
|
@ -1443,7 +1449,7 @@ code-example(format=".", language="bash").
|
|||
The preferred way to configure the strategy is to add a
|
||||
[<base href> element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) tag
|
||||
in the `<head>` of the `index.html`.
|
||||
+makeExample('router/ts/index.html','base-href')(format=".")
|
||||
+makeExample('router/ts/index.1.html','base-href')(format=".")
|
||||
:marked
|
||||
Without that tag, the browser may not be able to load resources
|
||||
(images, css, scripts) when "deep linking" into the app.
|
||||
|
|
Loading…
Reference in New Issue