docs(toh-5): Upgraded tutorial to new router

This commit is contained in:
Brandon Roberts 2016-06-19 00:20:38 -04:00 committed by Naomi Black
parent 2eae445504
commit f3189546a6
15 changed files with 364 additions and 267 deletions

View File

@ -54,7 +54,7 @@ nav a:hover {
color: #039be5; color: #039be5;
background-color: #CFD8DC; background-color: #CFD8DC;
} }
nav a.router-link-active { nav a.active {
color: #039be5; color: #039be5;
} }

View File

@ -8,7 +8,7 @@ import { HeroesComponent } from './heroes.component';
// #enddocregion // #enddocregion
// For testing only // For testing only
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; import { ROUTER_DIRECTIVES } from '@angular/router';
// #docregion // #docregion
@Component({ @Component({
@ -20,7 +20,6 @@ import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/route
directives: [HeroesComponent], directives: [HeroesComponent],
providers: [ providers: [
// #enddocregion // #enddocregion
ROUTER_PROVIDERS,
// #docregion // #docregion
HeroService HeroService
] ]

View File

@ -2,38 +2,27 @@
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
// #docregion import-router // #docregion import-router
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; import { ROUTER_DIRECTIVES } from '@angular/router';
// #enddocregion import-router // #enddocregion import-router
import { HeroService } from './hero.service'; import { HeroService } from './hero.service';
import { HeroesComponent } from './heroes.component';
@Component({ @Component({
selector: 'my-app', selector: 'my-app',
// #docregion template // #docregion template
template: ` template: `
<h1>{{title}}</h1> <h1>{{title}}</h1>
<a [routerLink]="['Heroes']">Heroes</a> <a [routerLink]="['/heroes']">Heroes</a>
<router-outlet></router-outlet> <router-outlet></router-outlet>
`, `,
// #enddocregion template // #enddocregion template
// #docregion directives-and-providers // #docregion directives-and-providers
directives: [ROUTER_DIRECTIVES], directives: [ROUTER_DIRECTIVES],
providers: [ providers: [
ROUTER_PROVIDERS,
HeroService HeroService
] ]
// #enddocregion directives-and-providers // #enddocregion directives-and-providers
}) })
// #docregion route-config
@RouteConfig([
{
path: '/heroes',
name: 'Heroes',
component: HeroesComponent
}
])
// #enddocregion route-config
export class AppComponent { export class AppComponent {
title = 'Tour of Heroes'; title = 'Tour of Heroes';
} }

View File

@ -0,0 +1,33 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import { HeroService } from './hero.service';
@Component({
selector: 'my-app',
// #docregion template
template: `
<h1>{{title}}</h1>
<nav>
// #docregion router-link-active
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
<a [routerLink]="['/heroes']" routerLinkActive="active">Heroes</a>
// #enddocregion router-link-active
</nav>
<router-outlet></router-outlet>
`,
// #enddocregion template
// #docregion style-urls
styleUrls: ['app/app.component.css'],
// #enddocregion style-urls
directives: [ROUTER_DIRECTIVES],
providers: [
HeroService
]
})
export class AppComponent {
title = 'Tour of Heroes';
}
// #enddocregion

View File

@ -24,6 +24,6 @@ nav a:hover {
color: #039be5; color: #039be5;
background-color: #CFD8DC; background-color: #CFD8DC;
} }
nav a.router-link-active { nav a.active {
color: #039be5; color: #039be5;
} }

View File

@ -1,13 +1,8 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated'; import { ROUTER_DIRECTIVES } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
// #docregion hero-detail-import
import { HeroDetailComponent } from './hero-detail.component';
// #enddocregion hero-detail-import
import { HeroService } from './hero.service'; import { HeroService } from './hero.service';
@Component({ @Component({
@ -16,8 +11,8 @@ import { HeroService } from './hero.service';
template: ` template: `
<h1>{{title}}</h1> <h1>{{title}}</h1>
<nav> <nav>
<a [routerLink]="['Dashboard']">Dashboard</a> <a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
<a [routerLink]="['Heroes']">Heroes</a> <a [routerLink]="['/heroes']" routerLinkActive="active">Heroes</a>
</nav> </nav>
<router-outlet></router-outlet> <router-outlet></router-outlet>
`, `,
@ -27,32 +22,9 @@ import { HeroService } from './hero.service';
// #enddocregion style-urls // #enddocregion style-urls
directives: [ROUTER_DIRECTIVES], directives: [ROUTER_DIRECTIVES],
providers: [ providers: [
ROUTER_PROVIDERS,
HeroService HeroService
] ]
}) })
@RouteConfig([
// #docregion dashboard-route
{
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
useAsDefault: true
},
// #enddocregion dashboard-route
// #docregion hero-detail-route
{
path: '/detail/:id',
name: 'HeroDetail',
component: HeroDetailComponent
},
// #enddocregion hero-detail-route
{
path: '/heroes',
name: 'Heroes',
component: HeroesComponent
}
])
export class AppComponent { export class AppComponent {
title = 'Tour of Heroes'; title = 'Tour of Heroes';
} }

View File

@ -0,0 +1,37 @@
// #docregion
import { provideRouter, RouterConfig } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
// #docregion hero-detail-import
import { HeroDetailComponent } from './hero-detail.component';
// #enddocregion hero-detail-import
export const routes: RouterConfig = [
// #docregion redirect-route
{
path: '',
redirectTo: '/dashboard',
terminal: true
},
// #enddocregion redirect-route
// #docregion dashboard-route
{
path: 'dashboard',
component: DashboardComponent
},
// #enddocregion dashboard-route
// #docregion hero-detail-route
{
path: 'detail/:id',
component: HeroDetailComponent
},
// #enddocregion hero-detail-route
{
path: 'heroes',
component: HeroesComponent
}
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];

View File

@ -0,0 +1,14 @@
// #docregion
import { provideRouter, RouterConfig } from '@angular/router';
import { HeroesComponent } from './heroes.component';
const routes: RouterConfig = [
{
path: '/heroes',
component: HeroesComponent
}
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];

View File

@ -0,0 +1,32 @@
// #docregion
import { provideRouter, RouterConfig } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
// #docregion hero-detail-import
import { HeroDetailComponent } from './hero-detail.component';
// #enddocregion hero-detail-import
export const routes: RouterConfig = [
{
path: '',
redirectTo: '/dashboard',
terminal: true
},
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'detail/:id',
component: HeroDetailComponent
},
{
path: 'heroes',
component: HeroesComponent
}
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];

View File

@ -2,7 +2,7 @@
// #docregion // #docregion
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
// #docregion import-router // #docregion import-router
import { Router } from '@angular/router-deprecated'; import { Router } from '@angular/router';
// #enddocregion import-router // #enddocregion import-router
import { Hero } from './hero'; import { Hero } from './hero';
@ -36,7 +36,7 @@ export class DashboardComponent implements OnInit {
// #docregion goto-detail // #docregion goto-detail
gotoDetail(hero: Hero) { gotoDetail(hero: Hero) {
let link = ['HeroDetail', { id: hero.id }]; let link = ['/detail', hero.id];
this.router.navigate(link); this.router.navigate(link);
} }
// #enddocregion goto-detail // #enddocregion goto-detail

View File

@ -1,11 +1,11 @@
// #docplaster // #docplaster
// #docregion // #docregion
// #docregion import-oninit, v2 // #docregion import-oninit, v2
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
// #enddocregion import-oninit // #enddocregion import-oninit
// #docregion import-route-params // #docregion import-activated-route
import { RouteParams } from '@angular/router-deprecated'; import { ActivatedRoute } from '@angular/router';
// #enddocregion import-route-params // #enddocregion import-activated-route
import { Hero } from './hero'; import { Hero } from './hero';
// #docregion import-hero-service // #docregion import-hero-service
@ -23,27 +23,36 @@ import { HeroService } from './hero.service';
}) })
// #enddocregion extract-template // #enddocregion extract-template
// #docregion implement // #docregion implement
export class HeroDetailComponent implements OnInit { export class HeroDetailComponent implements OnInit, OnDestroy {
// #enddocregion implement // #enddocregion implement
hero: Hero; hero: Hero;
sub: any;
// #docregion ctor // #docregion ctor
constructor( constructor(
private heroService: HeroService, private heroService: HeroService,
private routeParams: RouteParams) { private route: ActivatedRoute) {
} }
// #enddocregion ctor // #enddocregion ctor
// #docregion ng-oninit // #docregion ng-oninit
ngOnInit() { ngOnInit() {
// #docregion get-id // #docregion get-id
let id = +this.routeParams.get('id'); this.sub = this.route.params.subscribe(params => {
// #enddocregion get-id let id = +params['id'];
this.heroService.getHero(id) this.heroService.getHero(id)
.then(hero => this.hero = hero); .then(hero => this.hero = hero);
});
// #enddocregion get-id
} }
// #enddocregion ng-oninit // #enddocregion ng-oninit
// #docregion ng-ondestroy
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ng-ondestroy
// #docregion go-back // #docregion go-back
goBack() { goBack() {
window.history.back(); window.history.back();

View File

@ -1,7 +1,7 @@
// #docplaster // #docplaster
// #docregion // #docregion
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated'; import { Router } from '@angular/router';
import { Hero } from './hero'; import { Hero } from './hero';
import { HeroService } from './hero.service'; import { HeroService } from './hero.service';
@ -36,7 +36,7 @@ export class HeroesComponent implements OnInit {
onSelect(hero: Hero) { this.selectedHero = hero; } onSelect(hero: Hero) { this.selectedHero = hero; }
gotoDetail() { gotoDetail() {
this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]); this.router.navigate(['/detail', this.selectedHero.id]);
} }
// #docregion heroes-component-renaming // #docregion heroes-component-renaming
} }

View File

@ -1,5 +1,9 @@
// #docregion
import { bootstrap } from '@angular/platform-browser-dynamic'; import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { APP_ROUTER_PROVIDERS } from './app.routes';
bootstrap(AppComponent); bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS
]);

View File

@ -3,7 +3,7 @@
"files":[ "files":[
"!**/*.d.ts", "!**/*.d.ts",
"!**/*.js", "!**/*.js",
"!**/*.[1,2].*" "!**/*.[1,2,3].*"
], ],
"tags": ["tutorial", "tour", "heroes", "router"] "tags": ["tutorial", "tour", "heroes", "router"]
} }

View File

@ -15,7 +15,7 @@ figure.image-display
We'll add Angulars *Component Router* to our app to satisfy these requirements. We'll add Angulars *Component Router* to our app to satisfy these requirements.
.l-sub-section .l-sub-section
:marked :marked
The [Routing and Navigation](../guide/router-deprecated.html) chapter covers the router in more detail The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
than we will in this tutorial. than we will in this tutorial.
p Run the #[+liveExampleLink2('', 'toh-5')] for this part. p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
@ -146,47 +146,42 @@ code-example(language="bash").
.callout.is-important .callout.is-important
header base href is essential header base href is essential
:marked :marked
See the *base href* section of the [Router](../guide/router-deprecated.html#!#base-href) chapter to learn why this matters. See the *base href* section of the [Router](../guide/router.html#!#base-href) chapter to learn why this matters.
:marked :marked
### Make the router available. The Angular router is a combination of multiple provided services (`provideRouter`), multiple directives (`ROUTER_DIRECTIVES`),
The *Component Router* is a service. Like any service, we have to import it and make it and a configuration (`RouterConfig`). We'll configure our routes first:
available to the application by adding it to the `providers` array.
The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`), ### Configure and add the router
and a configuration decorator (`RouteConfig`). We'll import them all together:
+makeExample('toh-5/ts/app/app.component.2.ts', 'import-router', 'app/app.component.ts (router imports)')(format=".")
:marked
Next we update the `directives` and `providers` metadata arrays to *include* the router assets.
+makeExample('toh-5/ts/app/app.component.2.ts', 'directives-and-providers', 'app/app.component.ts (directives and providers)')(format=".")
:marked
Notice that we also removed the `HeroesComponent` from the `directives` array.
`AppComponent` no longer shows heroes; that will be the router's job.
We'll soon remove `<my-heroes>` from the template too.
### Add and configure the router Our application doesn't have a router yet. We'll create a configuration file for our routes that
does two things
The `AppComponent` doesn't have a router yet. We'll use the `@RouteConfig` decorator to simultaneously (a) configure that router with *routes*. (b) provide an export to add the router to our bootstrap
(a) assign a router to the component and (b) configure that router with *routes*.
*Routes* tell the router which views to display when a user clicks a link or *Routes* tell the router which views to display when a user clicks a link or
pastes a URL into the browser address bar. pastes a URL into the browser address bar.
Let's define our first route, a route to the `HeroesComponent`. Let's define our first route, a route to the `HeroesComponent`.
+makeExample('toh-5/ts/app/app.component.2.ts', 'route-config', 'app/app.component.ts (RouteConfig for heroes)')(format=".") +makeExample('toh-5/ts/app/app.routes.2.ts', '', 'app/app.routes.ts')(format=".")
:marked :marked
`@RouteConfig` takes an array of *route definitions*. The `RouterConfig` is an array of *route definitions*.
We have only one route definition at the moment but rest assured, we'll add more. We have only one route definition at the moment but rest assured, we'll add more.
This *route definition* has three parts: This *route definition* has two parts:
* **path**: the router matches this route's path to the URL in the browser address bar (`/heroes`). * **path**: the router matches this route's path to the URL in the browser address bar (`/heroes`).
* **name**: the official name of the route; it *must* begin with a capital letter to avoid confusion with the *path* (`Heroes`).
* **component**: the component that the router should create when navigating to this route (`HeroesComponent`). * **component**: the component that the router should create when navigating to this route (`HeroesComponent`).
.l-sub-section .l-sub-section
:marked :marked
Learn more about defining routes with @RouteConfig in the [Routing](../guide/router-deprecated.html) chapter. Learn more about defining routes with RouterConfig in the [Routing](../guide/router.html) chapter.
:marked
### Make the router available.
The *Component Router* is a service. We have to import our `APP_ROUTER_PROVIDERS` which
contains our configured router and make it available to the application by adding it to
the `bootstrap` array.
+makeExample('toh-5/ts/app/main.ts', '', 'app/main.ts')(format=".")
:marked :marked
### Router Outlet ### Router Outlet
@ -210,11 +205,11 @@ code-example(language="bash").
that tells the router where to navigate when the user clicks the link. that tells the router where to navigate when the user clicks the link.
We define a *routing instruction* with a *link parameters array*. We define a *routing instruction* with a *link parameters array*.
The array only has one element in our little sample, the quoted ***name* of the route** to follow. The array only has one element in our little sample, the quoted ***path* of the route** to follow.
Looking back at the route configuration, we confirm that `'Heroes'` is the name of the route to the `HeroesComponent`. Looking back at the route configuration, we confirm that `'/heroes'` is the path of the route to the `HeroesComponent`.
.l-sub-section .l-sub-section
:marked :marked
Learn about the *link parameters array* in the [Routing](../guide/router-deprecated.html#link-parameters-array) chapter. Learn about the *link parameters array* in the [Routing](../guide/router.html#link-parameters-array) chapter.
:marked :marked
Refresh the browser. We see only the app title. We don't see the heroes list. Refresh the browser. We see only the app title. We don't see the heroes list.
.l-sub-section .l-sub-section
@ -245,23 +240,27 @@ code-example(language="bash").
Well come back and make it more useful later. Well come back and make it more useful later.
### Configure the dashboard route ### Configure the dashboard route
Go back to `app.component.ts` and teach it to navigate to the dashboard. Go back to `app.routes.ts` and teach it to navigate to the dashboard.
Import the `DashboardComponent` so we can reference it in the dashboard route definition. Import the `DashboardComponent` so we can reference it in the dashboard route definition.
Add the following `'Dashboard'` route definition to the `@RouteConfig` array of definitions. Add the following `'Dashboard'` route definition to the `RouterConfig` array of definitions.
+makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app/app.component.ts (Dashboard route)')(format=".") +makeExample('toh-5/ts/app/app.routes.1.ts','dashboard-route', 'app/app.routes.ts (Dashboard route)')(format=".")
.l-sub-section .l-sub-section
:marked :marked
**useAsDefault** **Redirect**
We want the app to show the dashboard when it starts and We want the app to show the dashboard when it starts and
we want to see a nice URL in the browser address bar that says `/dashboard`. we want to see a nice URL in the browser address bar that says `/dashboard`.
Remember that the browser launches with `/` in the address bar. Remember that the browser launches with `/` in the address bar.
We don't have a route for that path and we'd rather not create one. We can use a redirect route to make this happen.
+makeExample('toh-5/ts/app/app.routes.1.ts','redirect-route', 'app/app.routes.ts (Redirect route)')(format=".")
.l-sub-section
:marked
Learn about the *redirects* in the [Routing](../guide/router.html#!#redirect) chapter.
Fortunately we can add the `useAsDefault: true` property to the *route definition* and the
router will display the dashboard when the browser URL doesn't match an existing route.
:marked :marked
Finally, add a dashboard navigation link to the template, just above the *Heroes* link. Finally, add a dashboard navigation link to the template, just above the *Heroes* link.
@ -364,16 +363,16 @@ code-example(format='').
### Configure a Route with a Parameter ### Configure a Route with a Parameter
Here's the *route definition* we'll use. Here's the *route definition* we'll use.
+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.ts (route to HeroDetailComponent)')(format=".") +makeExample('toh-5/ts/app/app.routes.1.ts','hero-detail-route', 'app/app.routes.ts (route to HeroDetailComponent)')(format=".")
:marked :marked
The colon (:) in the path indicates that `:id` is a placeholder to be filled with a specific hero `id` The colon (:) in the path indicates that `:id` is a placeholder to be filled with a specific hero `id`
when navigating to the `HeroDetailComponent`. when navigating to the `HeroDetailComponent`.
.l-sub-section .l-sub-section
:marked :marked
Of course we have to import the `HeroDetailComponent` before we create this route: Of course we have to import the `HeroDetailComponent` before we create this route:
+makeExample('toh-5/ts/app/app.component.ts','hero-detail-import')(format=".") +makeExample('toh-5/ts/app/app.routes.1.ts','hero-detail-import')(format=".")
:marked :marked
We're finished with the `AppComponent`. We're finished with the application routes.
We won't add a `'Hero Detail'` link to the template because users We won't add a `'Hero Detail'` link to the template because users
don't click a navigation *link* to view a particular hero. don't click a navigation *link* to view a particular hero.
@ -395,30 +394,36 @@ code-example(format='').
The template won't change. We'll display a hero the same way. The big changes are driven by how we get the hero. The template won't change. We'll display a hero the same way. The big changes are driven by how we get the hero.
We will no longer receive the hero in a parent component property binding. We will no longer receive the hero in a parent component property binding.
The new `HeroDetailComponent` should take the `id` parameter from the router's `RouteParams` service The new `HeroDetailComponent` should take the `id` parameter from the `params` observable
and use the `HeroService` to fetch the hero with that `id`. in the `ActivatedRoute` service and use the `HeroService` to fetch the hero with that `id`.
We need an import statement to reference the `RouteParams`. We need an import statement to reference the `ActivatedRoute`.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-route-params')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-activated-route')(format=".")
:marked :marked
We import the `HeroService`so we can fetch a hero. We import the `HeroService`so we can fetch a hero.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-hero-service')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-hero-service')(format=".")
:marked :marked
We import the `OnInit` interface because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook. We import the `OnInit` and `OnDestroy` interfaces because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook
and we'll clean up our `params` subscription in the `ngOnDestroy`.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-oninit')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-oninit')(format=".")
:marked :marked
We inject the both the `RouteParams` service and the `HeroService` into the constructor as we've done before, We inject the both the `ActivatedRoute` service and the `HeroService` into the constructor as we've done before,
making private variables for both: making private variables for both:
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ctor', 'app/hero-detail.component.ts (constructor)')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'ctor', 'app/hero-detail.component.ts (constructor)')(format=".")
:marked :marked
We tell the class that we want to implement the `OnInit` interface. We tell the class that we want to implement the `OnInit` and `OnDestroy` interfaces.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'implement')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'implement')(format=".")
:marked :marked
Inside the `ngOnInit` lifecycle hook, extract the `id` parameter value from the `RouteParams` service Inside the `ngOnInit` lifecycle hook, we _subscribe_ to the `params` observable to
extract the `id` parameter value from the `ActivateRoute` service
and use the `HeroService` to fetch the hero with that `id`. and use the `HeroService` to fetch the hero with that `id`.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ng-oninit', 'app/hero-detail.component.ts (ngOnInit)')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'ng-oninit', 'app/hero-detail.component.ts (ngOnInit)')(format=".")
:marked :marked
Notice how we extract the `id` by calling the `RouteParams.get` method. Inside the `ngOnDestroy` lifecycle hook, we _unsubscribe_ from the `params` subscription.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'ng-ondestroy', 'app/hero-detail.component.ts (ngOnDestroy)')(format=".")
:marked
Notice how we extract the `id` by calling the `subscribe` method
which will deliver our array of route parameters.
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'get-id')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.ts', 'get-id')(format=".")
:marked :marked
The hero `id` is a number. Route parameters are *always strings*. The hero `id` is a number. Route parameters are *always strings*.
@ -446,7 +451,7 @@ code-example(format='').
:marked :marked
Going back too far could take us out of the application. Going back too far could take us out of the application.
That's acceptable in a demo. We'd guard against it in a real application, That's acceptable in a demo. We'd guard against it in a real application,
perhaps with the [*routerCanDeactivate* hook](../api/router/CanDeactivate-interface.html). perhaps with the [*CanDeactivate* guard](../api/router/index/CanDeactivate-interface.html).
:marked :marked
Then we wire this method with an event binding to a *Back* button that we add to the bottom of the component template. Then we wire this method with an event binding to a *Back* button that we add to the bottom of the component template.
+makeExample('toh-5/ts/app/hero-detail.component.html', 'back-button')(format=".") +makeExample('toh-5/ts/app/hero-detail.component.html', 'back-button')(format=".")
@ -478,13 +483,13 @@ code-example(format='').
1. pass the array to the router's navigate method. 1. pass the array to the router's navigate method.
We wrote *link parameters arrays* in the `AppComponent` for the navigation links. We wrote *link parameters arrays* in the `AppComponent` for the navigation links.
Those arrays had only one element, the name of the destination route. Those arrays had only one element, the path of the destination route.
This array has two elements, the ***name*** of the destination route and a ***route parameter object*** This array has two elements, the ***path*** of the destination route and a ***route parameter***
with an `id` field set to the value of the selected hero's `id`. with an `id` field set to the value of the selected hero's `id`.
The two array items align with the ***name*** and ***:id*** token in the parameterized `HeroDetail` route configuration we added to `AppComponent` earlier in the chapter. The two array items align with the ***path*** and ***:id*** token in the parameterized `HeroDetail` route configuration we added to `app.routes.ts` earlier in the chapter.
+makeExample('toh-5/ts/app/app.component.ts','hero-detail-route', 'app/app.component.ts (hero detail route)')(format=".") +makeExample('toh-5/ts/app/app.routes.1.ts','hero-detail-route', 'app/app.routes.ts (hero detail route)')(format=".")
:marked :marked
The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way: The `DashboardComponent` doesn't have the router yet. We obtain it in the usual way:
import the `router` reference and inject it in the constructor (along with the `HeroService`): import the `router` reference and inject it in the constructor (along with the `HeroService`):
@ -615,10 +620,12 @@ figure.image-display
+makeExample('toh-5/ts/app/app.component.css', '', 'app/app.component.css (navigation styles)') +makeExample('toh-5/ts/app/app.component.css', '', 'app/app.component.css (navigation styles)')
.l-sub-section .l-sub-section
:marked :marked
**The *router-link-active* class** **The *routerLinkActive* directive**
The Angular Router adds the `router-link-active` class to the HTML navigation element The Angular Router provides a `routerLinkActive` directive we can use to
whose route matches the active route. All we have to do is define the style for it. Sweet! to add a class to the HTML navigation element whose route matches the active route.
All we have to do is define the style for it. Sweet!
+makeExample('toh-5/ts/app/app.component.3.ts', 'router-link-active', 'app/app.component.ts (active router links)')(format=".")
:marked :marked
Set the `AppComponent`s `styleUrls` property to this CSS file. Set the `AppComponent`s `styleUrls` property to this CSS file.
+makeExample('toh-5/ts/app/app.component.ts','style-urls', 'app/app.component.ts (styleUrls)')(format=".") +makeExample('toh-5/ts/app/app.component.ts','style-urls', 'app/app.component.ts (styleUrls)')(format=".")
@ -667,6 +674,7 @@ p.
.children .children
.file app.component.ts .file app.component.ts
.file app.component.css .file app.component.css
.file app.routes.ts
.file dashboard.component.css .file dashboard.component.css
.file dashboard.component.html .file dashboard.component.html
.file dashboard.component.ts .file dashboard.component.ts