docs: Update router guide to use Angular CLI (#20023)

PR Close #20023
This commit is contained in:
Brandon Roberts 2017-10-23 08:11:51 -05:00 committed by Kara Erickson
parent 3c8aa0b301
commit 1fb3c4ffee
137 changed files with 1819 additions and 1366 deletions

View File

@ -4,7 +4,7 @@ import { browser, element, by, ExpectedConditions } from 'protractor';
const numDashboardTabs = 5; const numDashboardTabs = 5;
const numCrises = 4; const numCrises = 4;
const numHeroes = 6; const numHeroes = 10;
const EC = ExpectedConditions; const EC = ExpectedConditions;
describe('Router', () => { describe('Router', () => {
@ -13,34 +13,34 @@ describe('Router', () => {
function getPageStruct() { function getPageStruct() {
const hrefEles = element.all(by.css('app-root > nav a')); const hrefEles = element.all(by.css('app-root > nav a'));
const crisisDetail = element.all(by.css('app-root > div > ng-component > ng-component > ng-component > div')).first(); const crisisDetail = element.all(by.css('app-root > div > app-crisis-center > app-crisis-list > app-crisis-detail > div')).first();
const heroDetail = element(by.css('app-root > div > ng-component')); const heroDetail = element(by.css('app-root > div > app-hero-detail'));
return { return {
hrefs: hrefEles, hrefs: hrefEles,
activeHref: element(by.css('app-root > nav a.active')), activeHref: element(by.css('app-root > nav a.active')),
crisisHref: hrefEles.get(0), crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('app-root > div > ng-component > ng-component li')), crisisList: element.all(by.css('app-root > div > app-crisis-center > app-crisis-list li')),
crisisDetail: crisisDetail, crisisDetail: crisisDetail,
crisisDetailTitle: crisisDetail.element(by.xpath('*[1]')), crisisDetailTitle: crisisDetail.element(by.xpath('*[1]')),
heroesHref: hrefEles.get(1), heroesHref: hrefEles.get(1),
heroesList: element.all(by.css('app-root > div > ng-component li')), heroesList: element.all(by.css('app-root > div > app-hero-list li')),
heroDetail: heroDetail, heroDetail: heroDetail,
heroDetailTitle: heroDetail.element(by.xpath('*[2]')), heroDetailTitle: heroDetail.element(by.xpath('*[2]')),
adminHref: hrefEles.get(2), adminHref: hrefEles.get(2),
adminPreloadList: element.all(by.css('app-root > div > ng-component > ng-component > ul > li')), adminPreloadList: element.all(by.css('app-root > div > app-admin > app-admin-dashboard > ul > li')),
loginHref: hrefEles.get(3), loginHref: hrefEles.get(3),
loginButton: element.all(by.css('app-root > div > ng-component > p > button')), loginButton: element.all(by.css('app-root > div > app-login > p > button')),
contactHref: hrefEles.get(4), contactHref: hrefEles.get(4),
contactCancelButton: element.all(by.buttonText('Cancel')), contactCancelButton: element.all(by.buttonText('Cancel')),
primaryOutlet: element.all(by.css('app-root > div > ng-component')), primaryOutlet: element.all(by.css('app-root > div > app-hero-list')),
secondaryOutlet: element.all(by.css('app-root > ng-component')) secondaryOutlet: element.all(by.css('app-root > app-compose-message'))
}; };
} }

View File

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

View File

@ -5,13 +5,9 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@Component({ @Component({
template: ` selector: 'app-admin-dashboard',
<p>Dashboard</p> templateUrl: './admin-dashboard.component.html',
styleUrls: ['./admin-dashboard.component.css']
<p>Session ID: {{ sessionId | async }}</p>
<a id="anchor"></a>
<p>Token: {{ token | async }}</p>
`
}) })
export class AdminDashboardComponent implements OnInit { export class AdminDashboardComponent implements OnInit {
sessionId: Observable<string>; sessionId: Observable<string>;

View File

@ -0,0 +1,5 @@
<p>Dashboard</p>
<p>Session ID: {{ sessionId | async }}</p>
<a id="anchor"></a>
<p>Token: {{ token | async }}</p>

View File

@ -0,0 +1,10 @@
<p>Dashboard</p>
<p>Session ID: {{ sessionId | async }}</p>
<a id="anchor"></a>
<p>Token: {{ token | async }}</p>
Preloaded Modules
<ul>
<li *ngFor="let module of modules">{{ module }}</li>
</ul>

View File

@ -4,22 +4,12 @@ import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { SelectivePreloadingStrategy } from '../selective-preloading-strategy'; import { SelectivePreloadingStrategyService } from '../../selective-preloading-strategy.service';
@Component({ @Component({
template: ` selector: 'app-admin-dashboard',
<p>Dashboard</p> templateUrl: './admin-dashboard.component.html',
styleUrls: ['./admin-dashboard.component.css']
<p>Session ID: {{ sessionId | async }}</p>
<a id="anchor"></a>
<p>Token: {{ token | async }}</p>
Preloaded Modules
<ul>
<li *ngFor="let module of modules">{{ module }}</li>
</ul>
`
}) })
export class AdminDashboardComponent implements OnInit { export class AdminDashboardComponent implements OnInit {
sessionId: Observable<string>; sessionId: Observable<string>;
@ -28,7 +18,7 @@ export class AdminDashboardComponent implements OnInit {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private preloadStrategy: SelectivePreloadingStrategy preloadStrategy: SelectivePreloadingStrategyService
) { ) {
this.modules = preloadStrategy.preloadedModules; this.modules = preloadStrategy.preloadedModules;
} }

View File

@ -3,10 +3,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './admin.component'; import { AdminComponent } from './admin/admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component'; import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component'; import { ManageCrisesComponent } from './manage-crises/manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component'; import { ManageHeroesComponent } from './manage-heroes/manage-heroes.component';
// #docregion admin-routes // #docregion admin-routes
const adminRoutes: Routes = [ const adminRoutes: Routes = [

View File

@ -3,13 +3,13 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './admin.component'; import { AdminComponent } from './admin/admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component'; import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component'; import { ManageCrisesComponent } from './manage-crises/manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component'; import { ManageHeroesComponent } from './manage-heroes/manage-heroes.component';
// #docregion admin-route // #docregion admin-route
import { AuthGuard } from '../auth-guard.service'; import { AuthGuard } from '../auth/auth.guard';
const adminRoutes: Routes = [ const adminRoutes: Routes = [
{ {

View File

@ -3,13 +3,13 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './admin.component'; import { AdminComponent } from './admin/admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component'; import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component'; import { ManageCrisesComponent } from './manage-crises/manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component'; import { ManageHeroesComponent } from './manage-heroes/manage-heroes.component';
// #docregion admin-route // #docregion admin-route
import { AuthGuard } from '../auth-guard.service'; import { AuthGuard } from '../auth/auth.guard';
// #docregion can-activate-child // #docregion can-activate-child
const adminRoutes: Routes = [ const adminRoutes: Routes = [

View File

@ -3,12 +3,12 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AdminComponent } from './admin.component'; import { AdminComponent } from './admin/admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component'; import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component'; import { ManageCrisesComponent } from './manage-crises/manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component'; import { ManageHeroesComponent } from './manage-heroes/manage-heroes.component';
import { AuthGuard } from '../auth-guard.service'; import { AuthGuard } from '../auth/auth.guard';
const adminRoutes: Routes = [ const adminRoutes: Routes = [
{ {

View File

@ -1,17 +0,0 @@
// #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

@ -2,10 +2,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { AdminComponent } from './admin.component'; import { AdminComponent } from './admin/admin.component';
import { AdminDashboardComponent } from './admin-dashboard.component'; import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
import { ManageCrisesComponent } from './manage-crises.component'; import { ManageCrisesComponent } from './manage-crises/manage-crises.component';
import { ManageHeroesComponent } from './manage-heroes.component'; import { ManageHeroesComponent } from './manage-heroes/manage-heroes.component';
import { AdminRoutingModule } from './admin-routing.module'; import { AdminRoutingModule } from './admin-routing.module';

View File

@ -0,0 +1,8 @@
<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>

View File

@ -0,0 +1,10 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-admin',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.css']
})
export class AdminComponent {
}

View File

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

View File

@ -0,0 +1 @@
<p>Manage your crises here</p>

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-manage-crises',
templateUrl: './manage-crises.component.html',
styleUrls: ['./manage-crises.component.css']
})
export class ManageCrisesComponent { }

View File

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

View File

@ -0,0 +1 @@
<p>Manage your heroes here</p>

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-manage-hereos',
templateUrl: './manage-heroes.component.html',
styleUrls: ['./manage-heroes.component.css']
})
export class ManageHeroesComponent { }

View File

@ -2,9 +2,9 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { HeroListComponent } from './hero-list.component'; import { HeroListComponent } from './hero-list/hero-list.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
// #docregion appRoutes // #docregion appRoutes
const appRoutes: Routes = [ const appRoutes: Routes = [

View File

@ -1,14 +1,19 @@
// #docregion // #docregion
// #docregion milestone3
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
// import { HeroListComponent } from './hero-list.component'; // <-- delete this line // #enddocregion milestone3
import { PageNotFoundComponent } from './not-found.component'; // import { HeroListComponent } from './hero-list/hero-list.component'; // <-- delete this line
// #docregion milestone3
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const appRoutes: Routes = [ const appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent }, { path: 'crisis-center', component: CrisisListComponent },
// #enddocregion milestone3
// { path: 'heroes', component: HeroListComponent }, // <-- delete this line // { path: 'heroes', component: HeroListComponent }, // <-- delete this line
// #docregion milestone3
{ path: '', redirectTo: '/heroes', pathMatch: 'full' }, { path: '', redirectTo: '/heroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent } { path: '**', component: PageNotFoundComponent }
]; ];
@ -25,3 +30,4 @@ const appRoutes: Routes = [
] ]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}
// #enddocregion milestone3

View File

@ -3,8 +3,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { ComposeMessageComponent } from './compose-message.component'; // #enddocregion v3
import { PageNotFoundComponent } from './not-found.component'; import { ComposeMessageComponent } from './compose-message/compose-message.component';
// #docregion v3
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const appRoutes: Routes = [ const appRoutes: Routes = [
// #enddocregion v3 // #enddocregion v3

View File

@ -2,9 +2,9 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { ComposeMessageComponent } from './compose-message.component'; import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { CanDeactivateGuard } from './can-deactivate-guard.service'; import { CanDeactivateGuard } from './can-deactivate.guard';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const appRoutes: Routes = [ const appRoutes: Routes = [
{ {
@ -25,9 +25,6 @@ const appRoutes: Routes = [
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
CanDeactivateGuard
] ]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

View File

@ -5,11 +5,10 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
// #enddocregion import-router // #enddocregion import-router
import { ComposeMessageComponent } from './compose-message.component'; import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { CanDeactivateGuard } from './can-deactivate-guard.service'; import { AuthGuard } from './auth/auth.guard';
import { AuthGuard } from './auth-guard.service';
const appRoutes: Routes = [ const appRoutes: Routes = [
@ -21,7 +20,7 @@ const appRoutes: Routes = [
// #docregion admin, admin-1 // #docregion admin, admin-1
{ {
path: 'admin', path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule', loadChildren: './admin/admin.module#AdminModule',
// #enddocregion admin-1 // #enddocregion admin-1
canLoad: [AuthGuard] canLoad: [AuthGuard]
// #docregion admin-1 // #docregion admin-1
@ -40,9 +39,6 @@ const appRoutes: Routes = [
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
CanDeactivateGuard
] ]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

View File

@ -8,11 +8,10 @@ import {
// #docregion preload-v1 // #docregion preload-v1
} from '@angular/router'; } from '@angular/router';
import { ComposeMessageComponent } from './compose-message.component'; import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { CanDeactivateGuard } from './can-deactivate-guard.service'; import { AuthGuard } from './auth/auth.guard';
import { AuthGuard } from './auth-guard.service';
const appRoutes: Routes = [ const appRoutes: Routes = [
{ {
@ -22,12 +21,12 @@ const appRoutes: Routes = [
}, },
{ {
path: 'admin', path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule', loadChildren: './admin/admin.module#AdminModule',
canLoad: [AuthGuard] canLoad: [AuthGuard]
}, },
{ {
path: 'crisis-center', path: 'crisis-center',
loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule' loadChildren: './crisis-center/crisis-center.module#CrisisCenterModule'
}, },
{ path: '', redirectTo: '/heroes', pathMatch: 'full' }, { path: '', redirectTo: '/heroes', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent } { path: '**', component: PageNotFoundComponent }
@ -49,9 +48,6 @@ const appRoutes: Routes = [
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
CanDeactivateGuard
] ]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

View File

@ -3,12 +3,11 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { ComposeMessageComponent } from './compose-message.component'; import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { CanDeactivateGuard } from './can-deactivate-guard.service'; import { AuthGuard } from './auth/auth.guard';
import { AuthGuard } from './auth-guard.service'; import { SelectivePreloadingStrategyService } from './selective-preloading-strategy.service';
import { SelectivePreloadingStrategy } from './selective-preloading-strategy';
const appRoutes: Routes = [ const appRoutes: Routes = [
{ {
@ -18,13 +17,13 @@ const appRoutes: Routes = [
}, },
{ {
path: 'admin', path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule', loadChildren: './admin/admin.module#AdminModule',
canLoad: [AuthGuard] canLoad: [AuthGuard]
}, },
// #docregion preload-v2 // #docregion preload-v2
{ {
path: 'crisis-center', path: 'crisis-center',
loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule', loadChildren: './crisis-center/crisis-center.module#CrisisCenterModule',
data: { preload: true } data: { preload: true }
}, },
// #enddocregion preload-v2 // #enddocregion preload-v2
@ -37,18 +36,13 @@ const appRoutes: Routes = [
RouterModule.forRoot( RouterModule.forRoot(
appRoutes, appRoutes,
{ {
enableTracing: true, // <-- debugging purposes only enableTracing: false, // <-- debugging purposes only
preloadingStrategy: SelectivePreloadingStrategy, preloadingStrategy: SelectivePreloadingStrategyService,
} }
) )
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
CanDeactivateGuard,
SelectivePreloadingStrategy
] ]
}) })
export class AppRoutingModule { } export class AppRoutingModule { }

View File

@ -0,0 +1,7 @@
<!-- #docregion -->
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>

View File

@ -1,18 +1,9 @@
/* First version */
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
// #docregion template templateUrl: 'app.component.html',
template: ` styleUrls: ['app.component.css']
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
`
// #enddocregion template
}) })
export class AppComponent { } export class AppComponent { }

View File

@ -0,0 +1,9 @@
<!-- #docregion -->
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>

View File

@ -4,24 +4,14 @@ import { Component } from '@angular/core';
// #docregion animation-imports // #docregion animation-imports
import { RouterOutlet } from '@angular/router'; import { RouterOutlet } from '@angular/router';
import { slideInAnimation } from './animations'; import { slideInAnimation } from './animations';
// #enddocregion animation-imports
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
// #docregion template templateUrl: 'app.component.html',
template: ` styleUrls: ['app.component.css'],
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
`,
animations: [ slideInAnimation ] animations: [ slideInAnimation ]
// #enddocregion template
}) })
// #enddocregion animation-imports
// #docregion function-binding // #docregion function-binding
export class AppComponent { export class AppComponent {
getAnimationData(outlet: RouterOutlet) { getAnimationData(outlet: RouterOutlet) {

View File

@ -0,0 +1,15 @@
<!-- #docregion -->
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<!-- #docregion contact-link -->
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
<!-- #enddocregion contact-link -->
</nav>
<!-- #docregion outlets -->
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
<!-- #enddocregion outlets -->

View File

@ -1,25 +0,0 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
// #docregion template
template: `
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
// #docregion contact-link
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
// #enddocregion contact-link
</nav>
// #docregion outlets
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
// #enddocregion outlets
`
// #enddocregion template
})
export class AppComponent { }

View File

@ -0,0 +1,12 @@
<!-- #docregion -->
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>

View File

@ -1,22 +0,0 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
// #docregion template
template: `
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
`
// #enddocregion template
})
export class AppComponent { }

View File

@ -0,0 +1,13 @@
<!-- #docregion -->
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>

View File

@ -1,25 +0,0 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
// #docregion template
template: `
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
`
// #enddocregion template
})
export class AppComponent {
}

View File

@ -0,0 +1,13 @@
<!-- #docregion -->
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>

View File

@ -6,23 +6,9 @@ import { slideInAnimation } from './animations';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
// #docregion template templateUrl: 'app.component.html',
template: ` styleUrls: ['app.component.css'],
<h1 class="title">Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/superheroes" routerLinkActive="active">Heroes</a>
<a routerLink="/admin" routerLinkActive="active">Admin</a>
<a routerLink="/login" routerLinkActive="active">Login</a>
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
</nav>
<div [@routeAnimation]="getAnimationData(routerOutlet)">
<router-outlet #routerOutlet="outlet"></router-outlet>
</div>
<router-outlet name="popup"></router-outlet>
`,
animations: [ slideInAnimation ] animations: [ slideInAnimation ]
// #enddocregion template
}) })
export class AppComponent { export class AppComponent {
getAnimationData(outlet: RouterOutlet) { getAnimationData(outlet: RouterOutlet) {

View File

@ -3,10 +3,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list.component'; import { HeroListComponent } from './hero-list/hero-list.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { PageNotFoundComponent as HeroDetailComponent } from './not-found.component'; import { PageNotFoundComponent as HeroDetailComponent } from './page-not-found/page-not-found.component';
// #docregion // #docregion
const appRoutes: Routes = [ const appRoutes: Routes = [

View File

@ -9,10 +9,10 @@ import { RouterModule, Routes } from '@angular/router';
// #enddocregion import-router // #enddocregion import-router
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { HeroListComponent } from './hero-list.component'; import { HeroListComponent } from './hero-list/hero-list.component';
// #enddocregion first-config // #enddocregion first-config
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
// #docregion first-config // #docregion first-config
// #docregion appRoutes // #docregion appRoutes

View File

@ -8,9 +8,9 @@ import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { HeroListComponent } from './hero-list.component'; import { HeroListComponent } from './hero-list/hero-list.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
@NgModule({ @NgModule({
imports: [ imports: [

View File

@ -7,8 +7,8 @@ import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { HeroesModule } from './heroes/heroes.module'; import { HeroesModule } from './heroes/heroes.module';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
@NgModule({ @NgModule({
// #docregion module-imports // #docregion module-imports
@ -27,3 +27,15 @@ import { PageNotFoundComponent } from './not-found.component';
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } export class AppModule { }
// #enddocregion
/*
// #docregion module-imports-2
imports: [
RouterModule.forChild([
// Heroes Routes
]),
AppRoutingModule
],
// #enddocregion module-imports-2
*/

View File

@ -6,19 +6,17 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { HeroesModule } from './heroes/heroes.module'; import { HeroesModule } from './heroes/heroes.module';
import { CrisisCenterModule } from './crisis-center/crisis-center.module'; import { CrisisCenterModule } from './crisis-center/crisis-center.module';
// #enddocregion crisis-center-module, admin-module // #enddocregion crisis-center-module
import { ComposeMessageComponent } from './compose-message.component';
// #docregion admin-module
import { AdminModule } from './admin/admin.module'; import { AdminModule } from './admin/admin.module';
// #docregion crisis-center-module // #docregion crisis-center-module
import { DialogService } from './dialog.service';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
@ -32,14 +30,11 @@ import { DialogService } from './dialog.service';
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
// #enddocregion admin-module, crisis-center-module // #enddocregion crisis-center-module
ComposeMessageComponent, ComposeMessageComponent,
// #docregion admin-module, crisis-center-module // #docregion crisis-center-module
PageNotFoundComponent PageNotFoundComponent
], ],
providers: [
DialogService
],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } export class AppModule { }

View File

@ -10,11 +10,10 @@ import { AppRoutingModule } from './app-routing.module';
import { HeroesModule } from './heroes/heroes.module'; import { HeroesModule } from './heroes/heroes.module';
import { CrisisCenterModule } from './crisis-center/crisis-center.module'; import { CrisisCenterModule } from './crisis-center/crisis-center.module';
import { ComposeMessageComponent } from './compose-message.component'; import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { AdminModule } from './admin/admin.module'; import { AdminModule } from './admin/admin.module';
import { DialogService } from './dialog.service';
@NgModule({ @NgModule({
imports: [ imports: [
@ -30,9 +29,6 @@ import { DialogService } from './dialog.service';
ComposeMessageComponent, ComposeMessageComponent,
PageNotFoundComponent PageNotFoundComponent
], ],
providers: [
DialogService
],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } export class AppModule { }

View File

@ -5,7 +5,7 @@ import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './not-found.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const routes: Routes = [ const routes: Routes = [

View File

@ -2,18 +2,16 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { AppRoutingModule } from './app-routing.module';
import { HeroesModule } from './heroes/heroes.module'; import { HeroesModule } from './heroes/heroes.module';
import { CrisisCenterModule } from './crisis-center/crisis-center.module'; import { CrisisCenterModule } from './crisis-center/crisis-center.module';
import { ComposeMessageComponent } from './compose-message.component'; import { AuthModule } from './auth/auth.module';
import { LoginRoutingModule } from './login-routing.module';
import { LoginComponent } from './login.component';
import { PageNotFoundComponent } from './not-found.component';
import { DialogService } from './dialog.service';
@NgModule({ @NgModule({
imports: [ imports: [
@ -21,18 +19,24 @@ import { DialogService } from './dialog.service';
FormsModule, FormsModule,
HeroesModule, HeroesModule,
CrisisCenterModule, CrisisCenterModule,
LoginRoutingModule, AuthModule,
AppRoutingModule AppRoutingModule
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
ComposeMessageComponent, ComposeMessageComponent,
LoginComponent,
PageNotFoundComponent PageNotFoundComponent
], ],
providers: [
DialogService
],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
}) })
export class AppModule { } // #docregion inspect-config
export class AppModule {
// Diagnostic only: inspect router configuration
constructor(router: Router) {
// Use a custom replacer to display function names in the route configs
const replacer = (key, value) => (typeof value === 'function') ? value.name : value;
console.log('Routes: ', JSON.stringify(router.config, replacer, 2));
}
}
// #enddocregion inspect-config

View File

@ -1,56 +1,58 @@
// #docplaster // #docplaster
// #docregion // #docregion auth, preload
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
// #docregion animations-module // #docregion animations-module
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
// #enddocregion animations-module // #enddocregion auth, animations-module
// #docregion inspect-config // #docregion inspect-config
import { Router } from '@angular/router'; import { Router } from '@angular/router';
// #enddocregion inspect-config // #enddocregion inspect-config
// #docregion auth
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { ComposeMessageComponent } from './compose-message/compose-message.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { HeroesModule } from './heroes/heroes.module'; import { HeroesModule } from './heroes/heroes.module';
import { ComposeMessageComponent } from './compose-message.component'; import { AuthModule } from './auth/auth.module';
import { LoginRoutingModule } from './login-routing.module';
import { LoginComponent } from './login.component';
import { PageNotFoundComponent } from './not-found.component';
import { DialogService } from './dialog.service';
// #docregion animations-module // #docregion animations-module
@NgModule({ @NgModule({
imports: [ imports: [
// #enddocregion animations-module // #enddocregion animations-module
BrowserModule, BrowserModule,
// #docregion animations-module
BrowserAnimationsModule,
// #enddocregion animations-module
FormsModule, FormsModule,
HeroesModule, HeroesModule,
LoginRoutingModule, AuthModule,
AppRoutingModule, AppRoutingModule,
// #docregion animations-module // #docregion animations-module
BrowserAnimationsModule
// #enddocregion animations-module
], ],
// #enddocregion animations-module
declarations: [ declarations: [
AppComponent, AppComponent,
ComposeMessageComponent, ComposeMessageComponent,
LoginComponent,
PageNotFoundComponent PageNotFoundComponent
], ],
providers: [
DialogService
],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
// #docregion animations-module
}) })
// #docregion inspect-config // #enddocregion animations-module
export class AppModule { export class AppModule {
// #enddocregion preload, auth
// Diagnostic only: inspect router configuration // Diagnostic only: inspect router configuration
constructor(router: Router) { constructor(router: Router) {
console.log('Routes: ', JSON.stringify(router.config, undefined, 2)); // Use a custom replacer to display function names in the route configs
// const replacer = (key, value) => (typeof value === 'function') ? value.name : value;
// console.log('Routes: ', JSON.stringify(router.config, replacer, 2));
} }
// #docregion preload, auth
} }
// #enddocregion inspect-config // #enddocregion preload, auth

View File

@ -1,11 +0,0 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate() {
console.log('AuthGuard#canActivate called');
return true;
}
}

View File

@ -1,24 +1,20 @@
// #docregion // #docregion
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './auth-guard.service'; import { AuthGuard } from './auth.guard';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { LoginComponent } from './login.component'; import { LoginComponent } from './login/login.component';
const loginRoutes: Routes = [ const authRoutes: Routes = [
{ path: 'login', component: LoginComponent } { path: 'login', component: LoginComponent }
]; ];
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild(loginRoutes) RouterModule.forChild(authRoutes)
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
AuthGuard,
AuthService
] ]
}) })
export class LoginRoutingModule {} export class AuthRoutingModule {}

View File

@ -0,0 +1,16 @@
// #docregion
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
console.log('AuthGuard#canActivate called');
return true;
}
}

View File

@ -1,17 +1,19 @@
// #docregion // #docregion
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
CanActivate, Router, import { Observable } from 'rxjs/Observable';
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
@Injectable() @Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {} constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
let url: string = state.url; let url: string = state.url;
return this.checkLogin(url); return this.checkLogin(url);

View File

@ -1,4 +1,3 @@
// #docregion
// #docregion can-activate-child // #docregion can-activate-child
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
@ -9,17 +8,23 @@ import {
} from '@angular/router'; } from '@angular/router';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
@Injectable() @Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild { export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private router: Router) {} constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
let url: string = state.url; let url: string = state.url;
return this.checkLogin(url); return this.checkLogin(url);
} }
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { canActivateChild(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
return this.canActivate(route, state); return this.canActivate(route, state);
} }

View File

@ -10,7 +10,9 @@ import {
} from '@angular/router'; } from '@angular/router';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
@Injectable() @Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild { export class AuthGuard implements CanActivate, CanActivateChild {
constructor(private authService: AuthService, private router: Router) {} constructor(private authService: AuthService, private router: Router) {}

View File

@ -10,7 +10,9 @@ import {
} from '@angular/router'; } from '@angular/router';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
@Injectable() @Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad { export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(private authService: AuthService, private router: Router) {} constructor(private authService: AuthService, private router: Router) {}

View File

@ -0,0 +1,25 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { LoginComponent } from './login/login.component';
import { AuthRoutingModule } from './auth-routing.module';
// #docregion v1
@NgModule({
imports: [
CommonModule,
FormsModule,
// #enddocregion v1
AuthRoutingModule
// #docregion v1
],
declarations: [
LoginComponent
]
})
export class AuthModule {}
// #enddocregion v1
// #enddocregion

View File

@ -4,7 +4,9 @@ import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { tap, delay } from 'rxjs/operators'; import { tap, delay } from 'rxjs/operators';
@Injectable() @Injectable({
providedIn: 'root'
})
export class AuthService { export class AuthService {
isLoggedIn = false; isLoggedIn = false;

View File

@ -1,16 +1,12 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AuthService } from './auth.service'; import { AuthService } from '../auth.service';
@Component({ @Component({
template: ` selector: 'app-login',
<h2>LOGIN</h2> templateUrl: './login.component.html',
<p>{{message}}</p> styleUrls: ['./login.component.css']
<p>
<button (click)="login()" *ngIf="!authService.isLoggedIn">Login</button>
<button (click)="logout()" *ngIf="authService.isLoggedIn">Logout</button>
</p>`
}) })
export class LoginComponent { export class LoginComponent {
message: string; message: string;

View File

@ -0,0 +1,6 @@
<h2>LOGIN</h2>
<p>{{message}}</p>
<p>
<button (click)="login()" *ngIf="!authService.isLoggedIn">Login</button>
<button (click)="logout()" *ngIf="authService.isLoggedIn">Logout</button>
</p>

View File

@ -2,16 +2,12 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router, import { Router,
NavigationExtras } from '@angular/router'; NavigationExtras } from '@angular/router';
import { AuthService } from './auth.service'; import { AuthService } from '../auth.service';
@Component({ @Component({
template: ` selector: 'app-login',
<h2>LOGIN</h2> templateUrl: './login.component.html',
<p>{{message}}</p> styleUrls: ['./login.component.css']
<p>
<button (click)="login()" *ngIf="!authService.isLoggedIn">Login</button>
<button (click)="logout()" *ngIf="authService.isLoggedIn">Logout</button>
</p>`
}) })
export class LoginComponent { export class LoginComponent {
message: string; message: string;

View File

@ -5,9 +5,11 @@ import { CanDeactivate,
ActivatedRouteSnapshot, ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router'; RouterStateSnapshot } from '@angular/router';
import { CrisisDetailComponent } from './crisis-center/crisis-detail.component'; import { CrisisDetailComponent } from './crisis-center/crisis-detail/crisis-detail.component';
@Injectable() @Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent> { export class CanDeactivateGuard implements CanDeactivate<CrisisDetailComponent> {
canDeactivate( canDeactivate(

View File

@ -7,7 +7,9 @@ export interface CanComponentDeactivate {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean; canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
} }
@Injectable() @Injectable({
providedIn: 'root'
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> { export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate) { canDeactivate(component: CanComponentDeactivate) {
return component.canDeactivate ? component.canDeactivate() : true; return component.canDeactivate ? component.canDeactivate() : true;

View File

@ -0,0 +1,3 @@
:host {
position: relative; bottom: 10%;
}

View File

@ -3,8 +3,9 @@ import { Component, HostBinding } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
@Component({ @Component({
selector: 'app-compose-message',
templateUrl: './compose-message.component.html', templateUrl: './compose-message.component.html',
styles: [ ':host { position: relative; bottom: 10%; }' ] styleUrls: ['./compose-message.component.css']
}) })
export class ComposeMessageComponent { export class ComposeMessageComponent {
details: string; details: string;

View File

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

View File

@ -0,0 +1 @@
<p>Welcome to the Crisis Center</p>

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-crisis-center-home',
templateUrl: './crisis-center-home.component.html',
styleUrls: ['./crisis-center-home.component.css']
})
export class CrisisCenterHomeComponent { }

View File

@ -3,10 +3,10 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisCenterHomeComponent } from './crisis-center-home.component'; import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
// #docregion routes // #docregion routes
const crisisCenterRoutes: Routes = [ const crisisCenterRoutes: Routes = [

View File

@ -3,30 +3,23 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisCenterHomeComponent } from './crisis-center-home.component'; import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
// #enddocregion routes // #enddocregion routes
// #docregion can-deactivate-guard // #docregion can-deactivate-guard
import { CanDeactivateGuard } from '../can-deactivate-guard.service'; import { CanDeactivateGuard } from '../can-deactivate.guard';
// #enddocregion can-deactivate-guard // #enddocregion can-deactivate-guard
// #docregion crisis-detail-resolver // #docregion crisis-detail-resolver
import { CrisisDetailResolver } from './crisis-detail-resolver.service'; import { CrisisDetailResolverService } from './crisis-detail-resolver.service';
// #enddocregion crisis-detail-resolver // #enddocregion crisis-detail-resolver
// #docregion routes // #docregion routes
const crisisCenterRoutes: Routes = [ const crisisCenterRoutes: Routes = [
// #enddocregion routes // #enddocregion routes
// #docregion redirect, routes
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
// #enddocregion redirect, routes
// #docregion routes // #docregion routes
{ {
path: 'crisis-center', path: 'crisis-center',
@ -45,7 +38,7 @@ const crisisCenterRoutes: Routes = [
// #enddocregion can-deactivate-guard // #enddocregion can-deactivate-guard
// #docregion crisis-detail-resolver // #docregion crisis-detail-resolver
resolve: { resolve: {
crisis: CrisisDetailResolver crisis: CrisisDetailResolverService
} }
// #enddocregion crisis-detail-resolver // #enddocregion crisis-detail-resolver
// #docregion routes // #docregion routes

View File

@ -3,20 +3,15 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisCenterHomeComponent } from './crisis-center-home.component'; import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
// #docregion can-deactivate-guard // #docregion can-deactivate-guard
import { CanDeactivateGuard } from '../can-deactivate-guard.service'; import { CanDeactivateGuard } from '../can-deactivate.guard';
const crisisCenterRoutes: Routes = [ const crisisCenterRoutes: Routes = [
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
{ {
path: 'crisis-center', path: 'crisis-center',
component: CrisisCenterComponent, component: CrisisCenterComponent,

View File

@ -3,25 +3,15 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisCenterHomeComponent } from './crisis-center-home.component'; import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service'; import { CanDeactivateGuard } from '../can-deactivate.guard';
import { CrisisDetailResolverService } from './crisis-detail-resolver.service';
// #docregion crisis-detail-resolver
import { CrisisDetailResolver } from './crisis-detail-resolver.service';
// #enddocregion crisis-detail-resolver
const crisisCenterRoutes: Routes = [ const crisisCenterRoutes: Routes = [
// #docregion redirect
{
path: '',
redirectTo: '/crisis-center',
pathMatch: 'full'
},
// #enddocregion redirect
{ {
path: 'crisis-center', path: 'crisis-center',
component: CrisisCenterComponent, component: CrisisCenterComponent,
@ -35,7 +25,7 @@ const crisisCenterRoutes: Routes = [
component: CrisisDetailComponent, component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard], canDeactivate: [CanDeactivateGuard],
resolve: { resolve: {
crisis: CrisisDetailResolver crisis: CrisisDetailResolverService
} }
}, },
{ {
@ -48,18 +38,13 @@ const crisisCenterRoutes: Routes = [
} }
]; ];
// #docregion crisis-detail-resolver
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild(crisisCenterRoutes) RouterModule.forChild(crisisCenterRoutes)
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
CrisisDetailResolver
] ]
}) })
export class CrisisCenterRoutingModule { } export class CrisisCenterRoutingModule { }
// #enddocregion crisis-detail-resolver
// #enddocregion // #enddocregion

View File

@ -3,13 +3,13 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { CrisisCenterHomeComponent } from './crisis-center-home.component'; import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisDetailComponent } from './crisis-detail.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
import { CanDeactivateGuard } from '../can-deactivate-guard.service'; import { CanDeactivateGuard } from '../can-deactivate.guard';
import { CrisisDetailResolver } from './crisis-detail-resolver.service'; import { CrisisDetailResolverService } from './crisis-detail-resolver.service';
const crisisCenterRoutes: Routes = [ const crisisCenterRoutes: Routes = [
{ {
@ -25,7 +25,7 @@ const crisisCenterRoutes: Routes = [
component: CrisisDetailComponent, component: CrisisDetailComponent,
canDeactivate: [CanDeactivateGuard], canDeactivate: [CanDeactivateGuard],
resolve: { resolve: {
crisis: CrisisDetailResolver crisis: CrisisDetailResolverService
} }
}, },
{ {
@ -44,9 +44,6 @@ const crisisCenterRoutes: Routes = [
], ],
exports: [ exports: [
RouterModule RouterModule
],
providers: [
CrisisDetailResolver
] ]
}) })
export class CrisisCenterRoutingModule { } export class CrisisCenterRoutingModule { }

View File

@ -1,10 +0,0 @@
// #docregion
import { Component } from '@angular/core';
@Component({
template: `
<h2>CRISIS CENTER</h2>
<router-outlet></router-outlet>
`
})
export class CrisisCenterComponent { }

View File

@ -1,36 +0,0 @@
// #docplaster
// #docregion
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { CrisisService } from './crisis.service';
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 { CrisisCenterRoutingModule } from './crisis-center-routing.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
CrisisCenterRoutingModule
],
declarations: [
CrisisCenterComponent,
CrisisListComponent,
CrisisCenterHomeComponent,
CrisisDetailComponent
],
// #docregion providers
providers: [
CrisisService
]
// #enddocregion providers
})
export class CrisisCenterModule {}
// #enddocregion

View File

@ -1,15 +1,12 @@
// #docplaster
// #docregion // #docregion
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CrisisService } from './crisis.service'; import { CrisisCenterHomeComponent } from './crisis-center-home/crisis-center-home.component';
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisCenterComponent } from './crisis-center.component'; import { CrisisCenterComponent } from './crisis-center/crisis-center.component';
import { CrisisListComponent } from './crisis-list.component'; import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';
import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisDetailComponent } from './crisis-detail.component';
import { CrisisCenterRoutingModule } from './crisis-center-routing.module'; import { CrisisCenterRoutingModule } from './crisis-center-routing.module';
@ -24,12 +21,6 @@ import { CrisisCenterRoutingModule } from './crisis-center-routing.module';
CrisisListComponent, CrisisListComponent,
CrisisCenterHomeComponent, CrisisCenterHomeComponent,
CrisisDetailComponent CrisisDetailComponent
],
providers: [
CrisisService
] ]
}) })
// #docregion crisis-center-module-export
export class CrisisCenterModule {} export class CrisisCenterModule {}
// #enddocregion crisis-center-module-export
// #enddocregion

View File

@ -0,0 +1,2 @@
<h2>CRISIS CENTER</h2>
<router-outlet></router-outlet>

View File

@ -0,0 +1,9 @@
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'app-crisis-center',
templateUrl: './crisis-center.component.html',
styleUrls: ['./crisis-center.component.css']
})
export class CrisisCenterComponent { }

View File

@ -0,0 +1,11 @@
// #docregion
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CrisisDetailResolverService {
constructor() { }
}

View File

@ -1,27 +1,31 @@
// #docregion // #docregion
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Router, Resolve, RouterStateSnapshot, import { Router, Resolve, RouterStateSnapshot,
ActivatedRouteSnapshot } from '@angular/router'; ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable, of, EMPTY as empty } from 'rxjs';
import { map, take } from 'rxjs/operators'; import { mergeMap, take } from 'rxjs/operators';
import { Crisis, CrisisService } from './crisis.service'; import { CrisisService } from './crisis.service';
import { Crisis } from './crisis';
@Injectable() @Injectable({
export class CrisisDetailResolver implements Resolve<Crisis> { providedIn: 'root'
})
export class CrisisDetailResolverService implements Resolve<Crisis> {
constructor(private cs: CrisisService, private router: Router) {} constructor(private cs: CrisisService, private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Crisis> | Observable<never> {
let id = route.paramMap.get('id'); let id = route.paramMap.get('id');
return this.cs.getCrisis(id).pipe( return this.cs.getCrisis(id).pipe(
take(1), take(1),
map(crisis => { mergeMap(crisis => {
if (crisis) { if (crisis) {
return crisis; return of(crisis);
} else { // id not found } else { // id not found
this.router.navigate(['/crisis-center']); this.router.navigate(['/crisis-center']);
return null; return empty;
} }
}) })
); );

View File

@ -1,30 +1,18 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component, OnInit, HostBinding } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router'; import { ActivatedRoute, Router, ParamMap } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
import { Crisis, CrisisService } from './crisis.service'; import { CrisisService } from '../crisis.service';
import { DialogService } from '../dialog.service'; import { Crisis } from '../crisis';
import { DialogService } from '../../dialog.service';
@Component({ @Component({
template: ` selector: 'app-crisis-detail',
<div *ngIf="crisis"> templateUrl: './crisis-detail.component.html',
<h3>"{{ editName }}"</h3> styleUrls: ['./crisis-detail.component.css']
<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 { export class CrisisDetailComponent implements OnInit {
crisis: Crisis; crisis: Crisis;

View File

@ -0,0 +1,3 @@
input {
width: 20em
}

View File

@ -0,0 +1,13 @@
<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>

View File

@ -4,26 +4,13 @@ import { Component, OnInit, HostBinding } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { Crisis } from './crisis.service'; import { Crisis } from '../crisis';
import { DialogService } from '../dialog.service'; import { DialogService } from '../../dialog.service';
@Component({ @Component({
template: ` selector: 'app-crisis-detail',
<div *ngIf="crisis"> templateUrl: './crisis-detail.component.html',
<h3>"{{ editName }}"</h3> styleUrls: ['./crisis-detail.component.css']
<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 { export class CrisisDetailComponent implements OnInit {
crisis: Crisis; crisis: Crisis;

View File

@ -1,44 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
// #docregion relative-navigation-router-link
template: `
<ul class="items">
<li *ngFor="let crisis of crises$ | async"
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>
<router-outlet></router-outlet>
`
// #enddocregion relative-navigation-router-link
})
export class CrisisListComponent implements OnInit {
crises$: Observable<Crisis[]>;
selectedId: number;
constructor(
private service: CrisisService,
private route: ActivatedRoute
) {}
ngOnInit() {
this.crises$ = this.route.paramMap.pipe(
switchMap((params: ParamMap) => {
this.selectedId = +params.get('id');
return this.service.getCrises();
})
);
}
}

View File

@ -1,35 +1,26 @@
// #docregion
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router'; import { ActivatedRoute, ParamMap } from '@angular/router';
import { Crisis, CrisisService } from './crisis.service'; import { CrisisService } from '../crisis.service';
import { Crisis } from '../crisis';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
@Component({ @Component({
template: ` selector: 'app-crisis-list',
<ul class="items"> templateUrl: './crisis-list.component.html',
<li *ngFor="let crisis of crises$ | async" styleUrls: ['./crisis-list.component.css']
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>
<router-outlet></router-outlet>
`
}) })
export class CrisisListComponent implements OnInit { export class CrisisListComponent implements OnInit {
crises$: Observable<Crisis[]>; crises$: Observable<Crisis[]>;
selectedId: number; selectedId: number;
// #docregion ctor
constructor( constructor(
private service: CrisisService, private service: CrisisService,
private route: ActivatedRoute private route: ActivatedRoute
) {} ) {}
// #enddocregion ctor
ngOnInit() { ngOnInit() {
this.crises$ = this.route.paramMap.pipe( this.crises$ = this.route.paramMap.pipe(

View File

@ -1,41 +1,37 @@
/* items class */ /* CrisisListComponent's private CSS styles */
.items { .crises {
margin: 0 0 2em 0; margin: 0 0 2em 0;
list-style-type: none; list-style-type: none;
padding: 0; padding: 0;
width: 24em; width: 24em;
} }
.items li { .crises li {
cursor: pointer;
position: relative; position: relative;
left: 0; cursor: pointer;
background-color: #EEE; background-color: #EEE;
margin: .5em; margin: .5em;
padding: .3em 0; padding: .3em 0;
height: 1.6em; height: 1.6em;
border-radius: 4px; border-radius: 4px;
} }
.items li a {
display: block; .crises li:hover {
text-decoration: none;
}
.items li:hover {
color: #607D8B; color: #607D8B;
background-color: #DDD; background-color: #DDD;
left: .1em; left: .1em;
} }
.items li.selected {
background-color: #CFD8DC; .crises a {
color: white; color: #888;
text-decoration: none;
display: block;
} }
.items li.selected:hover {
background-color: #BBD8DC; .crises a:hover {
color:#607D8B;
} }
.items .text {
position: relative; .crises .badge {
top: -3px;
}
.items .badge {
display: inline-block; display: inline-block;
font-size: small; font-size: small;
color: white; color: white;
@ -46,6 +42,38 @@
left: -1px; left: -1px;
top: -4px; top: -4px;
height: 1.8em; height: 1.8em;
min-width: 16px;
text-align: right;
margin-right: .8em; margin-right: .8em;
border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px;
} }
button {
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
font-family: Arial;
}
button:hover {
background-color: #cfd8dc;
}
button.delete {
position: relative;
left: 194px;
top: -32px;
background-color: gray !important;
color: white;
}
.crises li.selected {
background-color: #CFD8DC;
color: white;
}
.crises li.selected:hover {
background-color: #BBD8DC;
}

View File

@ -0,0 +1,12 @@
<!-- #docregion relative-navigation-router-link -->
<ul class="crises">
<li *ngFor="let crisis of crises$ | async"
[class.selected]="crisis.id === selectedId">
<a [routerLink]="[crisis.id]">
<span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
</a>
</li>
</ul>
<router-outlet></router-outlet>
<!-- #enddocregion relative-navigation-router-link -->

View File

@ -0,0 +1,34 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CrisisService } from '../crisis.service';
import { Crisis } from '../crisis';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Component({
selector: 'app-crisis-list',
templateUrl: './crisis-list.component.html',
styleUrls: ['./crisis-list.component.css']
})
export class CrisisListComponent implements OnInit {
crises$: Observable<Crisis[]>;
selectedId: number;
// #docregion ctor
constructor(
private service: CrisisService,
private route: ActivatedRoute
) {}
// #enddocregion ctor
ngOnInit() {
this.crises$ = this.route.paramMap.pipe(
switchMap(params => {
this.selectedId = +params.get('id');
return this.service.getCrises();
})
);
}
}

View File

@ -1,27 +1,22 @@
// #docplaster // #docplaster
// #docregion , mock-crises // #docregion
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
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'),
];
// #enddocregion mock-crises
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { MessageService } from '../message.service';
import { Crisis } from './crisis';
import { CRISES } from './mock-crises';
@Injectable() @Injectable({
providedIn: 'root'
})
export class CrisisService { export class CrisisService {
static nextCrisisId = 100; static nextCrisisId = 100;
private crises$: BehaviorSubject<Crisis[]> = new BehaviorSubject<Crisis[]>(CRISES); private crises$: BehaviorSubject<Crisis[]> = new BehaviorSubject<Crisis[]>(CRISES);
constructor(private messageService: MessageService) { }
getCrises() { return this.crises$; } getCrises() { return this.crises$; }
getCrisis(id: number | string) { getCrisis(id: number | string) {
@ -34,7 +29,7 @@ export class CrisisService {
addCrisis(name: string) { addCrisis(name: string) {
name = name.trim(); name = name.trim();
if (name) { if (name) {
let crisis = new Crisis(CrisisService.nextCrisisId++, name); let crisis = { id: CrisisService.nextCrisisId++, name };
CRISES.push(crisis); CRISES.push(crisis);
this.crises$.next(CRISES); this.crises$.next(CRISES);
} }

View File

@ -0,0 +1,4 @@
export class Crisis {
id: number;
name: string;
}

Some files were not shown because too many files have changed in this diff Show More