docs(router): Added and organized more router dev guide content

Moved all heroes functionality into milestone 2
Crisis Center initial functionality is milestone 3
Admin feature module as milestone 4 including route guard examples
Updated milestone 5 to lazy load admin feature module
Added examples for CanLoad, CanActivateChildren guard, component-less routes
Added section on explanation of ActivatedRoute
Added section on animating route components
Added section on relative navigation
This commit is contained in:
Brandon Roberts 2016-08-26 23:19:27 -05:00 committed by Naomi Black
parent 4d46d7c1e4
commit c15a68e591
53 changed files with 1422 additions and 757 deletions

View File

@ -16,8 +16,8 @@ describe('Router', function () {
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > ng-component > ng-component li')),
crisisDetail: element(by.css('my-app > ng-component > ng-component > div')),
crisisDetailTitle: element(by.css('my-app > ng-component > ng-component > div > h3')),
crisisDetail: element(by.css('my-app > ng-component > ng-component > ng-component > div')),
crisisDetailTitle: element(by.css('my-app > ng-component > ng-component > ng-component > div > h3')),
heroesHref: hrefEles.get(1),
heroesList: element.all(by.css('my-app > ng-component li')),
@ -34,7 +34,7 @@ describe('Router', function () {
expect(page.hrefs.count()).toEqual(4, 'should be 4 dashboard choices');
expect(page.crisisHref.getText()).toEqual('Crisis Center');
expect(page.heroesHref.getText()).toEqual('Heroes');
expect(page.adminHref.getText()).toEqual('Crisis Admin');
expect(page.adminHref.getText()).toEqual('Admin');
expect(page.loginHref.getText()).toEqual('Login');
});
@ -118,7 +118,6 @@ describe('Router', function () {
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);
let inputEle = page.crisisDetail.element(by.css('input'));

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
template: `
<p>Dashboard</p>
`
})
export class AdminDashboardComponent { }

View File

@ -6,15 +6,14 @@ import 'rxjs/add/operator/map';
@Component({
template: `
<h3>CRISIS ADMINISTRATION</h3>
<p>Manage your crises here</p>
<p>Dashboard</p>
<p>Session ID: {{ sessionId | async }}</p>
<a id="anchor"></a>
<p>Token: {{ token | async }}</p>
`
})
export class CrisisAdminComponent implements OnInit {
export class AdminDashboardComponent implements OnInit {
sessionId: Observable<string>;
token: Observable<string>;

View File

@ -0,0 +1,17 @@
// #docregion
import { Component } from '@angular/core';
@Component({
template: `
<h3>ADMIN</h3>
<nav>
<a routerLink="./" routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }">Dashboard</a>
<a routerLink="./crises" routerLinkActive="active">Manage Crises</a>
<a routerLink="./heroes" routerLinkActive="active">Manage Heroes</a>
</nav>
<router-outlet></router-outlet>
`
})
export class AdminComponent {
}

View File

@ -0,0 +1,28 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AdminComponent } from './admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component';
import { adminRouting } from './admin.routing';
@NgModule({
imports: [
CommonModule,
adminRouting
],
declarations: [
AdminComponent,
AdminDashboardComponent,
ManageCrisesComponent,
ManageHeroesComponent
]
})
// #docregion admin-module-export
export class AdminModule {}
// #enddocregion admin-module-export
// #enddocregion

View File

@ -0,0 +1,31 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminComponent } from './admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component';
// #docregion admin-routes
const adminRoutes: Routes = [
{
path: 'admin',
component: AdminComponent,
children: [
{
path: '',
children: [
{ path: 'crises', component: ManageCrisesComponent },
{ path: 'heroes', component: ManageHeroesComponent },
{ path: '', component: AdminDashboardComponent }
]
}
]
}
];
export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
// #enddocregion admin-routes
// #enddocregion

View File

@ -0,0 +1,37 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminComponent } from './admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component';
// #docregion admin-route, can-activate-child
import { AuthGuard } from '../auth-guard.service';
const adminRoutes: Routes = [
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
children: [
{ path: 'crises', component: ManageCrisesComponent },
{ path: 'heroes', component: ManageHeroesComponent },
{ path: '', component: AdminDashboardComponent }
],
// #enddocregion admin-route
// #docregion can-activate-child
canActivateChild: [AuthGuard]
// #docregion admin-route
}
]
}
];
export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
// #enddocregion

View File

@ -0,0 +1,35 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminComponent } from './admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component';
// #docregion admin-route
import { AuthGuard } from '../auth-guard.service';
// #docregion can-activate-child
const adminRoutes: Routes = [
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
canActivateChild: [AuthGuard],
children: [
{ path: 'crises', component: ManageCrisesComponent },
{ path: 'heroes', component: ManageHeroesComponent },
{ path: '', component: AdminDashboardComponent }
]
}
]
}
];
export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
// #enddocregion

View File

@ -0,0 +1,34 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminComponent } from './admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component';
// #docregion admin-route
import { AuthGuard } from '../auth-guard.service';
const adminRoutes: Routes = [
{
path: '',
component: AdminComponent,
canActivate: [AuthGuard],
children: [
{
path: '',
canActivateChild: [AuthGuard],
children: [
{ path: 'crises', component: ManageCrisesComponent },
{ path: 'heroes', component: ManageHeroesComponent },
{ path: '', component: AdminDashboardComponent }
]
}
]
}
];
export const adminRouting: ModuleWithProviders = RouterModule.forChild(adminRoutes);
// #enddocregion

View File

@ -3,8 +3,7 @@ import { Component } from '@angular/core';
@Component({
template: `
<h3>CRISIS ADMINISTRATION</h3>
<p>Manage your crises here</p>
`
})
export class CrisisAdminComponent { }
export class ManageCrisesComponent { }

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
template: `
<p>Manage your heroes here</p>
`
})
export class ManageHeroesComponent { }

View File

@ -6,7 +6,7 @@ import { Component } from '@angular/core';
selector: 'my-app',
// #docregion template
template: `
<h1>Component Router</h1>
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>

View File

@ -7,7 +7,7 @@ import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Component Router</h1>
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>

View File

@ -1,7 +1,7 @@
/* tslint:disable:no-unused-variable */
// #docplaster
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { Router } from '@angular/router';
@Component({
selector: 'my-app',
@ -36,7 +36,7 @@ import { Router } from '@angular/router';
*/
// #docregion template
template: `
<h1 class="title">Component Router</h1>
<h1 class="title">Angular Router</h1>
<nav>
<a [routerLink]="['/crisis-center']">Crisis Center</a>
<a [routerLink]="['/crisis-center/1', { foo: 'foo' }]">Dragon Crisis</a>

View File

@ -1,16 +1,15 @@
// #docregion
import { Component } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1 class="title">Component Router</h1>
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }">Crisis Center</a>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/crisis-center/admin" routerLinkActive="active">Crisis Admin</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
</nav>
<router-outlet></router-outlet>
`

View File

@ -1,17 +1,16 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1 class="title">Component Router</h1>
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }">Crisis Center</a>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/crisis-center/admin" routerLinkActive="active">Crisis Admin</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
</nav>
<router-outlet></router-outlet>

View File

@ -4,11 +4,10 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
// #docregion router-basics
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { routing,
appRoutingProviders } from './app.routing';
appRoutingProviders } from './app.routing';
import { HeroListComponent } from './hero-list.component';
import { CrisisListComponent } from './crisis-list.component';

View File

@ -1,14 +1,14 @@
// #docplaster
// #docregion
// #docregion hero-import
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { routing,
appRoutingProviders } from './app.routing';
appRoutingProviders } from './app.routing';
// #docregion hero-import
import { HeroesModule } from './heroes/heroes.module';
import { CrisisListComponent } from './crisis-list.component';

View File

@ -1,24 +1,34 @@
// #docplaster
// #docregion
// #docregion crisis-center-module, admin-module
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { routing,
appRoutingProviders } from './app.routing';
appRoutingProviders } from './app.routing';
import { HeroesModule } from './heroes/heroes.module';
// #docregion crisis-center-module
import { CrisisCenterModule } from './crisis-center/crisis-center.module';
// #enddocregion crisis-center-module
// #docregion admin-module
import { AdminModule } from './admin/admin.module';
// #docregion crisis-center-module
import { DialogService } from './dialog.service';
import { DialogService } from './dialog.service';
@NgModule({
imports: [
BrowserModule,
CommonModule,
FormsModule,
routing,
HeroesModule,
CrisisCenterModule
CrisisCenterModule,
// #enddocregion crisis-center-module
AdminModule
// #docregion crisis-center-module
],
declarations: [
AppComponent
@ -31,3 +41,4 @@ import { DialogService } from './dialog.service';
})
export class AppModule {
}
// #enddocregion

View File

@ -2,25 +2,30 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { routing,
appRoutingProviders } from './app.routing';
const routes: Routes = [
import { HeroesModule } from './heroes/heroes.module';
import { CrisisCenterModule } from './crisis-center/crisis-center.module';
];
import { DialogService } from './dialog.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
routing,
HeroesModule,
CrisisCenterModule
],
declarations: [
AppComponent
],
providers: [
appRoutingProviders,
DialogService
],
bootstrap: [ AppComponent ]
})

View File

@ -0,0 +1,28 @@
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
const routes: Routes = [
];
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
],
declarations: [
AppComponent
],
providers: [
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}

View File

@ -3,22 +3,24 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { AppComponent } from './app.component';
import { routing,
appRoutingProviders } from './app.routing';
appRoutingProviders } from './app.routing';
import { HeroesModule } from './heroes/heroes.module';
import { HeroesModule } from './heroes/heroes.module';
import { CrisisCenterModule } from './crisis-center/crisis-center.module';
import { LoginComponent } from './login.component';
import { LoginComponent } from './login.component';
import { DialogService } from './dialog.service';
import { DialogService } from './dialog.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
routing,
HeroesModule
HeroesModule,
CrisisCenterModule
],
declarations: [
AppComponent,

View File

@ -12,12 +12,16 @@ import { HeroListComponent } from './hero-list.component';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { HeroDetailComponent } from './heroes/hero-detail.component';
import { PageNotFoundComponent } from './not-found.component';
import { PageNotFoundComponent as HomeComponent } from './not-found.component';
// #enddocregion base-routes
// #docregion
// #docregion route-config
const appRoutes: Routes = [
// #docregion route-defs
// #docregion hero-detail-route
{ path: 'hero/:id', component: HeroDetailComponent },
// #enddocregion hero-detail-route
{ path: 'crisis-center', component: CrisisCenterComponent },
{
path: 'heroes',
@ -26,10 +30,8 @@ const appRoutes: Routes = [
title: 'Heroes List'
}
},
{ path: '', component: HomeComponent },
// #enddocregion route-defs
// #docregion hero-detail-route
{ path: 'hero/:id', component: HeroDetailComponent },
// #enddocregion hero-detail-route
{ path: '**', component: PageNotFoundComponent }
];

View File

@ -3,10 +3,10 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisListComponent } from './crisis-center/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
const appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent }
{ path: 'crisis-center', component: CrisisCenterComponent }
];
export const appRoutingProviders: any[] = [

View File

@ -9,24 +9,9 @@ import { loginRoutes,
import { CanDeactivateGuard } from './can-deactivate-guard.service';
// #docregion lazy-load-crisis-center
const crisisCenterRoutes: Routes = [
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
{
path: 'crisis-center',
loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule'
}
];
const appRoutes: Routes = [
...loginRoutes,
...crisisCenterRoutes
...loginRoutes
];
// #enddocregion lazy-load-crisis-center
export const appRoutingProviders: any[] = [
authProviders,
@ -34,14 +19,3 @@ export const appRoutingProviders: any[] = [
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
// #enddocregion
/* A link parameters array
// #docregion heroes-redirect
{
path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
// #enddocregion heroes-redirect
*/

View File

@ -1,32 +1,36 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { ModuleWithProviders } from '@angular/core';
// #docregion import-router
import { Routes, RouterModule } from '@angular/router';
import { Routes, RouterModule } from '@angular/router';
// #enddocregion import-router
import { loginRoutes,
authProviders } from './login.routing';
authProviders } from './login.routing';
import { CanDeactivateGuard } from './can-deactivate-guard.service';
// #docregion can-load-guard
import { AuthGuard } from './auth-guard.service';
// #enddocregion can-load-guard
// #docregion lazy-load-crisis-center
const crisisCenterRoutes: Routes = [
// #docregion lazy-load-admin, can-load-guard
const adminRoutes: Routes = [
{
path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
{
path: 'crisis-center',
loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule'
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule',
// #enddocregion lazy-load-admin
canLoad: [AuthGuard]
// #docregion lazy-load-admin
}
];
// #enddocregion can-load-guard
const appRoutes: Routes = [
...loginRoutes,
...crisisCenterRoutes
...adminRoutes
];
// #enddocregion lazy-load-crisis-center
// #enddocregion lazy-load-admin
export const appRoutingProviders: any[] = [
authProviders,

View File

@ -1,22 +1,37 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.checkLogin(url);
}
checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) { return true; }
// Store the attempted URL for redirecting
this.authService.redirectUrl = state.url;
this.authService.redirectUrl = url;
// Navigate to the login page
// Navigate to the login page with extras
this.router.navigate(['/login']);
return false;
}
}
// #enddocregion
/*
// #docregion can-load-interface
export class AuthGuard implements CanActivate, CanLoad {
// #enddocregion can-load-interface
*/

View File

@ -0,0 +1,40 @@
// #docplaster
// #docregion
// #docregion can-activate-child
import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
CanActivateChild
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.checkLogin(url);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}
// #enddocregion can-activate-child
checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) { return true; }
// Store the attempted URL for redirecting
this.authService.redirectUrl = url;
// Navigate to the login page
this.router.navigate(['/login']);
return false;
}
// #docregion can-activate-child
}
// #enddocregion

View File

@ -0,0 +1,47 @@
// #docplaster
// #docregion
import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
CanActivateChild,
NavigationExtras
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.checkLogin(url);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}
checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) { return true; }
// Store the attempted URL for redirecting
this.authService.redirectUrl = url;
// Create a dummy session id
let sessionId = 123456789;
// Set our navigation extras object
// that contains our global query params and fragment
let navigationExtras: NavigationExtras = {
queryParams: { 'session_id': sessionId },
fragment: 'anchor'
};
// Navigate to the login page with extras
this.router.navigate(['/login'], navigationExtras);
return false;
}
}

View File

@ -1,20 +1,42 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
NavigationExtras } from '@angular/router';
import { AuthService } from './auth.service';
// #docplaster
// #docregion, admin-can-load
import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
CanActivateChild,
NavigationExtras,
CanLoad, Route
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.checkLogin(url);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}
canLoad(route: Route): boolean {
let url = `/${route.path}`;
return this.checkLogin(url);
}
// #enddocregion admin-can-load
checkLogin(url: string): boolean {
if (this.authService.isLoggedIn) { return true; }
// Store the attempted URL for redirecting
this.authService.redirectUrl = state.url;
this.authService.redirectUrl = url;
// Create a dummy session id
let sessionId = 123456789;
@ -30,4 +52,5 @@ export class AuthGuard implements CanActivate {
this.router.navigate(['/login'], navigationExtras);
return false;
}
// #docregion admin-can-load
}

View File

@ -13,11 +13,11 @@ export class AuthService {
// store the URL so we can redirect after logging in
redirectUrl: string;
login() {
login(): Observable<boolean> {
return Observable.of(true).delay(1000).do(val => this.isLoggedIn = true);
}
logout() {
logout(): void {
this.isLoggedIn = false;
}
}

View File

@ -3,7 +3,6 @@ import { Injectable } from '@angular/core';
import { CanDeactivate,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { CrisisDetailComponent } from './crisis-center/crisis-detail.component';
@ -14,7 +13,7 @@ export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent>
component: CrisisDetailComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
): Promise<boolean> | boolean {
// Get the Crisis Center ID
console.log(route.params['id']);

View File

@ -4,12 +4,12 @@ import { CanDeactivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
export interface CanComponentDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate): Observable<boolean> | Promise<boolean> | boolean {
canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true;
}
}

View File

@ -0,0 +1,13 @@
// #docregion
// #docplaster
import { Component } from '@angular/core';
// #docregion minus-imports
@Component({
template: `
<p>Welcome to the Crisis Center</p>
`
})
export class CrisisCenterHomeComponent { }
// #enddocregion minus-imports
// #enddocregion

View File

@ -1,3 +1,4 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
@ -6,7 +7,8 @@ import { CommonModule } from '@angular/common';
import { CrisisService } from './crisis.service';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { crisisCenterRouting } from './crisis-center.routing';
@ -20,13 +22,15 @@ import { crisisCenterRouting } from './crisis-center.routing';
declarations: [
CrisisCenterComponent,
CrisisListComponent,
CrisisCenterHomeComponent,
CrisisDetailComponent
],
// #docregion providers
// #docregion providers
providers: [
CrisisService
]
// #enddocregion providers
// #enddocregion providers
})
export class CrisisCenterModule {}
// #enddocregion

View File

@ -9,10 +9,10 @@ import { CrisisService } from './crisis.service';
import { CrisisDetailResolve } from './crisis-detail-resolve.service';
// #enddocregion crisis-detail-resolve
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { crisisCenterRouting } from './crisis-center.routing';
@ -25,8 +25,8 @@ import { crisisCenterRouting } from './crisis-center.routing';
declarations: [
CrisisCenterComponent,
CrisisListComponent,
CrisisDetailComponent,
CrisisAdminComponent
CrisisCenterHomeComponent,
CrisisDetailComponent
],
// #docregion crisis-detail-resolve

View File

@ -1,10 +1,12 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component';
// #docregion routes
const crisisCenterRoutes: Routes = [
@ -12,11 +14,24 @@ const crisisCenterRoutes: Routes = [
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
{ path: ':id', component: CrisisDetailComponent },
{ path: '', component: CrisisListComponent }
{
path: '',
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
];
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion routes
// #docregion routes
// #enddocregion

View File

@ -1,29 +1,65 @@
// #docregion
// #docplaster
// #docregion routes
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component';
// #enddocregion routes
// #docregion can-deactivate-guard
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
// #enddocregion can-deactivate-guard
// #docregion crisis-detail-resolve
import { CrisisDetailResolve } from './crisis-detail-resolve.service';
// #enddocregion crisis-detail-resolve
// #docregion routes
const crisisCenterRoutes: Routes = [
// #docregion redirect
// #enddocregion routes
// #docregion redirect, routes
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
// #enddocregion redirect
// #enddocregion redirect, routes
// #docregion routes
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
{ path: ':id', component: CrisisDetailComponent },
{ path: '', component: CrisisListComponent }
{
path: '',
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent,
// #enddocregion routes
// #docregion can-deactivate-guard
canDeactivate: [CanDeactivateGuard],
// #enddocregion can-deactivate-guard
// #docregion crisis-detail-resolve
resolve: {
crisis: CrisisDetailResolve
}
// #enddocregion crisis-detail-resolve
// #docregion routes
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
// #docregion routes
];
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion routes
// #enddocregion

View File

@ -3,11 +3,12 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component';
// #docregion can-deactivate-guard
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
const crisisCenterRoutes: Routes = [
@ -20,20 +21,20 @@ const crisisCenterRoutes: Routes = [
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
// #docregion admin-route-no-guard
{
path: 'admin',
component: CrisisAdminComponent
},
// #enddocregion admin-route-no-guard
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard]
},
{
path: '',
component: CrisisListComponent
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard]
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
@ -41,15 +42,3 @@ const crisisCenterRoutes: Routes = [
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion
/*
// #docregion auth-guard
import { AuthGuard } from '../auth.guard';
{
path: 'admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
}
// #enddocregion auth-guard
*/

View File

@ -1,57 +0,0 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
import { AuthGuard } from '../auth-guard.service';
const crisisCenterRoutes: Routes = [
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
{
path: 'admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
},
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard]
},
// #docregion default-route
{
path: '',
component: CrisisListComponent
}
// #enddocregion default-route
]
}
];
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion
/*
// #docregion auth-guard
import { AuthGuard } from '../auth.guard';
{
path: 'admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
}
// #enddocregion auth-guard
*/

View File

@ -1,53 +0,0 @@
// #docplaster
// #docregion
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
import { AuthGuard } from '../auth-guard.service';
// #docregion crisis-detail-resolve
import { CrisisDetailResolve } from './crisis-detail-resolve.service';
// #enddocregion crisis-detail-resolve
const crisisCenterRoutes: Routes = [
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
// #docregion admin-route
{
path: 'admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
},
// #enddocregion admin-route
// #docregion crisis-detail-resolve
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard],
resolve: {
crisis: CrisisDetailResolve
}
},
// #enddocregion crisis-detail-resolve
{
path: '',
component: CrisisListComponent
}
]
}
];
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);

View File

@ -3,49 +3,49 @@
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisAdminComponent } from './crisis-admin.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service';
import { AuthGuard } from '../auth-guard.service';
// #docregion crisis-detail-resolve
import { CrisisDetailResolve } from './crisis-detail-resolve.service';
// #enddocregion crisis-detail-resolve
// #docregion lazy-load-crisis-center
const crisisCenterRoutes: Routes = [
// #docregion redirect
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
// #enddocregion redirect
{
path: 'crisis-center',
component: CrisisCenterComponent,
children: [
// #docregion admin-route
{
path: 'admin',
component: CrisisAdminComponent,
canActivate: [AuthGuard]
},
// #enddocregion admin-route
// #docregion crisis-detail-resolve
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard],
resolve: {
crisis: CrisisDetailResolve
}
// #enddocregion crisis-detail-resolve
},
{
path: '',
component: CrisisListComponent
component: CrisisListComponent,
children: [
{
path: ':id',
component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard],
resolve: {
crisis: CrisisDetailResolve
}
},
{
path: '',
component: CrisisCenterHomeComponent
}
]
}
]
}
];
export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);
// #enddocregion lazy-load-crisis-center
// #enddocregion

View File

@ -2,7 +2,6 @@
import { Injectable } from '@angular/core';
import { Router, Resolve,
ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Crisis, CrisisService } from './crisis.service';
@ -10,7 +9,7 @@ import { Crisis, CrisisService } from './crisis.service';
export class CrisisDetailResolve implements Resolve<Crisis> {
constructor(private cs: CrisisService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot): Observable<any> | Promise<any> | any {
resolve(route: ActivatedRouteSnapshot): Promise<Crisis>|boolean {
let id = +route.params['id'];
return this.cs.getCrisis(id).then(crisis => {

View File

@ -1,12 +1,12 @@
// #docplaster
// #docregion
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Component, OnInit,
HostBinding, trigger, transition,
animate, style, state } from '@angular/core';
import { ActivatedRoute, Router, Params } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { DialogService } from '../dialog.service';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
@Component({
// #docregion template
@ -26,16 +26,47 @@ import { Subscription } from 'rxjs/Subscription';
</div>
`,
// #enddocregion template
styles: ['input {width: 20em}']
styles: ['input {width: 20em}'],
animations: [
trigger('routeAnimation', [
state('*',
style({
opacity: 1,
transform: 'translateX(0)'
})
),
transition('void => *', [
style({
opacity: 0,
transform: 'translateX(-100%)'
}),
animate('0.2s ease-in')
]),
transition('* => void', [
animate('0.5s ease-out', style({
opacity: 0,
transform: 'translateY(100%)'
}))
])
])
]
})
// #docregion cancel-save
export class CrisisDetailComponent implements OnInit, OnDestroy {
export class CrisisDetailComponent implements OnInit {
@HostBinding('@routeAnimation') get routeAnimation() {
return true;
}
@HostBinding('style.display') get display() {
return 'block';
}
@HostBinding('style.position') get position() {
return 'absolute';
}
crisis: Crisis;
editName: string;
// #enddocregion ngOnDestroy
private sub: Subscription;
// #enddocregion ngOnDestroy
// #enddocregion cancel-save
constructor(
@ -47,9 +78,7 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
// #docregion ngOnInit
ngOnInit() {
this.sub = this.route
.params
.subscribe(params => {
this.route.params.forEach((params: Params) => {
let id = +params['id'];
this.service.getCrisis(id)
.then(crisis => {
@ -64,14 +93,6 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
}
// #enddocregion ngOnInit
// #enddocregion ngOnDestroy
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
}
}
// #enddocregion ngOnDestroy
// #docregion cancel-save
cancel() {
this.gotoCrises();
@ -84,7 +105,7 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
// #enddocregion cancel-save
// #docregion cancel-save-only
canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
canDeactivate(): Promise<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
@ -95,15 +116,16 @@ export class CrisisDetailComponent implements OnInit, OnDestroy {
}
// #enddocregion cancel-save-only
// #docregion gotoCrises
// #docregion gotoCrises, relative-navigation
gotoCrises() {
let crisisId = this.crisis ? this.crisis.id : null;
// Pass along the hero id if available
// so that the CrisisListComponent can select that hero.
// Pass along the crisis id if available
// so that the CrisisListComponent can select that crisis.
// Add a totally useless `foo` parameter for kicks.
this.router.navigate(['/crisis-center', { id: crisisId, foo: 'foo' }]);
// Relative navigation back to the crises
this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });
}
// #enddocregion gotoCrises
// #enddocregion gotoCrises, relative-navigation
// #docregion cancel-save
}
// #enddocregion cancel-save

View File

@ -1,11 +1,12 @@
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, HostBinding,
trigger, transition,
animate, style, state } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Crisis } from './crisis.service';
import { DialogService } from '../dialog.service';
import { Observable } from 'rxjs/Observable';
@Component({
template: `
@ -23,10 +24,45 @@ import { Observable } from 'rxjs/Observable';
</p>
</div>
`,
styles: ['input {width: 20em}']
styles: ['input {width: 20em}'],
// #enddocregion template
animations: [
trigger('routeAnimation', [
state('*',
style({
opacity: 1,
transform: 'translateX(0)'
})
),
transition('void => *', [
style({
opacity: 0,
transform: 'translateX(-100%)'
}),
animate('0.2s ease-in')
]),
transition('* => void', [
animate('0.5s ease-out', style({
opacity: 0,
transform: 'translateY(100%)'
}))
])
])
]
})
export class CrisisDetailComponent implements OnInit {
@HostBinding('@routeAnimation') get routeAnimation() {
return true;
}
@HostBinding('style.display') get display() {
return 'block';
}
@HostBinding('style.position') get position() {
return 'absolute';
}
crisis: Crisis;
editName: string;
@ -34,7 +70,7 @@ export class CrisisDetailComponent implements OnInit {
private route: ActivatedRoute,
private router: Router,
public dialogService: DialogService
) { }
) { }
// #docregion crisis-detail-resolve
ngOnInit() {
@ -54,7 +90,7 @@ export class CrisisDetailComponent implements OnInit {
this.gotoCrises();
}
canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
canDeactivate(): Promise<boolean> | boolean {
// Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged
if (!this.crisis || this.crisis.name === this.editName) {
return true;
@ -67,12 +103,12 @@ export class CrisisDetailComponent implements OnInit {
// #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.
// Pass along the crisis id if available
// so that the CrisisListComponent can select that crisis.
// Add a totally useless `foo` parameter for kicks.
// #docregion gotoCrises-navigate
// Absolute link
this.router.navigate(['/crisis-center', { id: crisisId, foo: 'foo' }]);
// Relative navigation back to the crises
this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });
// #enddocregion gotoCrises-navigate
}
// #enddocregion gotoCrises

View File

@ -23,10 +23,12 @@ export class CrisisListComponent implements OnInit, OnDestroy {
selectedId: number;
private sub: Subscription;
// #docregion relative-navigation-ctor
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router) {}
// #enddocregion relative-navigation-ctor
ngOnInit() {
this.sub = this.route
@ -45,7 +47,14 @@ export class CrisisListComponent implements OnInit, OnDestroy {
// #docregion select
onSelect(crisis: Crisis) {
// Absolute link
this.router.navigate(['/crisis-center', crisis.id]);
this.router.navigate([crisis.id]);
}
// #enddocregion select
}
// #enddocregion
/*
// #docregion relative-navigation-router-link
<a [routerLink]="[crisis.id]">{{ crisis.name }}</a>
// #enddocregion relative-navigation-router-link
*/

View File

@ -1,10 +1,9 @@
// #docplaster
// #docregion
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, Params } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
template: `
@ -15,38 +14,38 @@ import { Subscription } from 'rxjs/Subscription';
<span class="badge">{{crisis.id}}</span> {{crisis.name}}
</li>
</ul>
<router-outlet></router-outlet>
`
})
export class CrisisListComponent implements OnInit, OnDestroy {
export class CrisisListComponent implements OnInit {
crises: Crisis[];
private selectedId: number;
private sub: Subscription;
public selectedId: number;
constructor(
private service: CrisisService,
private route: ActivatedRoute,
private router: Router) { }
private router: Router
) { }
isSelected(crisis: Crisis) { return crisis.id === this.selectedId; }
isSelected(crisis: Crisis) {
return crisis.id === this.selectedId;
}
ngOnInit() {
this.sub = this.route
.params
.subscribe(params => {
this.selectedId = +params['id'];
this.service.getCrises()
.then(crises => this.crises = crises);
});
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
}
this.route.params.forEach((params: Params) => {
this.selectedId = params['id'];
this.service.getCrises()
.then(crises => this.crises = crises);
});
}
// #docregion relative-navigation
onSelect(crisis: Crisis) {
// Navigate with Absolute link
this.router.navigate(['/crisis-center', crisis.id]);
this.selectedId = crisis.id;
// Navigate with relative link
this.router.navigate([crisis.id], { relativeTo: this.route });
}
// #enddocregion relative-navigation
}

View File

@ -1,10 +1,11 @@
// #docplaster
// #docregion
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
// #docregion imports
import { Router, ActivatedRoute, Params } from '@angular/router';
// #enddocregion imports
import { Hero, HeroService } from './hero.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
template: `
@ -23,34 +24,26 @@ import { Subscription } from 'rxjs/Subscription';
</div>
`
})
export class HeroDetailComponent implements OnInit, OnDestroy {
export class HeroDetailComponent implements OnInit {
hero: Hero;
// #docregion ngOnInit
private sub: Subscription;
// #enddocregion ngOnInit
// #docregion ctor
constructor(
private route: ActivatedRoute,
private router: Router,
private service: HeroService) {}
private service: HeroService
) {}
// #enddocregion ctor
// #docregion ngOnInit
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
this.route.params.forEach((params: Params) => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
}
// #enddocregion ngOnInit
// #docregion ngOnDestroy
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ngOnDestroy
// #docregion gotoHeroes
gotoHeroes() { this.router.navigate(['/heroes']); }
// #enddocregion gotoHeroes

View File

@ -1,11 +1,15 @@
// #docplaster
// #docregion
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
// #docregion route-animation-imports
import { Component, OnInit, HostBinding,
trigger, transition, animate,
style, state } from '@angular/core';
// #enddocregion route-animation-imports
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Hero, HeroService } from './hero.service';
import { Subscription } from 'rxjs/Subscription';
// #docregion route-animation
@Component({
template: `
<h2>HEROES</h2>
@ -21,15 +25,48 @@ import { Subscription } from 'rxjs/Subscription';
<button (click)="gotoHeroes()">Back</button>
</p>
</div>
`
`,
animations: [
trigger('routeAnimation', [
state('*',
style({
opacity: 1,
transform: 'translateX(0)'
})
),
transition('void => *', [
style({
opacity: 0,
transform: 'translateX(-100%)'
}),
animate('0.2s ease-in')
]),
transition('* => void', [
animate('0.5s ease-out', style({
opacity: 0,
transform: 'translateY(100%)'
}))
])
])
]
})
export class HeroDetailComponent implements OnInit, OnDestroy {
// #docregion route-animation-host-binding
export class HeroDetailComponent implements OnInit {
// #enddocregion route-animation
@HostBinding('@routeAnimation') get routeAnimation() {
return true;
}
@HostBinding('style.display') get display() {
return 'block';
}
@HostBinding('style.position') get position() {
return 'absolute';
}
hero: Hero;
// #docregion ngOnInit
private sub: Subscription;
// #enddocregion ngOnInit
// #docregion ctor
constructor(
private route: ActivatedRoute,
@ -39,19 +76,13 @@ export class HeroDetailComponent implements OnInit, OnDestroy {
// #docregion ngOnInit
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.route.params.forEach((params: Params) => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
}
// #enddocregion ngOnInit
// #docregion ngOnDestroy
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ngOnDestroy
// #docregion gotoHeroes-navigate
gotoHeroes() {
let heroId = this.hero ? this.hero.id : null;
@ -60,4 +91,6 @@ export class HeroDetailComponent implements OnInit, OnDestroy {
this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);
}
// #enddocregion gotoHeroes-navigate
// #docregion route-animation-host-binding
}
// #enddocregion route-animation-host-binding

View File

@ -1,13 +1,12 @@
// #docplaster
// #docregion
// TODO SOMEDAY: Feature Componetized like CrisisCenter
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Component, OnInit } from '@angular/core';
// #docregion import-router
import { Router, ActivatedRoute } from '@angular/router';
import { Router, ActivatedRoute, Params } from '@angular/router';
// #enddocregion import-router
import { Hero, HeroService } from './hero.service';
import { Subscription } from 'rxjs/Subscription';
@Component({
// #docregion template
@ -23,32 +22,26 @@ import { Subscription } from 'rxjs/Subscription';
`
// #enddocregion template
})
export class HeroListComponent implements OnInit, OnDestroy {
export class HeroListComponent implements OnInit {
heroes: Hero[];
// #docregion ctor
private selectedId: number;
private sub: Subscription;
constructor(
private service: HeroService,
private route: ActivatedRoute,
private router: Router) {}
private router: Router
) {}
// #enddocregion ctor
ngOnInit() {
this.sub = this.route
.params
.subscribe(params => {
this.route.params.forEach((params: Params) => {
this.selectedId = +params['id'];
this.service.getHeroes()
.then(heroes => this.heroes = heroes);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ctor
// #docregion isSelected

View File

@ -32,7 +32,7 @@ export class LoginComponent {
if (this.authService.isLoggedIn) {
// Get the redirect URL from our auth service
// If no redirect has been set, use the default
let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/crisis-center/admin';
let redirect = this.authService.redirectUrl ? this.authService.redirectUrl : '/admin';
// #docregion preserve
// Set our navigation extras object

View File

@ -122,7 +122,7 @@
"router": {
"title": "Routing & Navigation",
"intro": "Discover the basics of screen navigation with the Angular 2 Component Router."
"intro": "Discover the basics of screen navigation with the Angular 2 Router."
},
"security": {

File diff suppressed because it is too large Load Diff