parent
4dcea96b6d
commit
fd46bf4970
|
@ -11,7 +11,6 @@ import { HeroesComponent } from './heroes.component';
|
||||||
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
|
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
|
||||||
|
|
||||||
// #docregion
|
// #docregion
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
template: `
|
template: `
|
||||||
|
@ -20,13 +19,12 @@ import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/route
|
||||||
`,
|
`,
|
||||||
directives: [HeroesComponent],
|
directives: [HeroesComponent],
|
||||||
providers: [
|
providers: [
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
ROUTER_PROVIDERS,
|
ROUTER_PROVIDERS,
|
||||||
// #docregion
|
// #docregion
|
||||||
HeroService
|
HeroService
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'Tour of Heroes';
|
title = 'Tour of Heroes';
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -10,14 +10,14 @@ 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,
|
ROUTER_PROVIDERS,
|
||||||
|
@ -37,4 +37,3 @@ import { HeroesComponent } from './heroes.component';
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'Tour of Heroes';
|
title = 'Tour of Heroes';
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
/* #docplaster */
|
/* #docregion */
|
||||||
/* #docregion css */
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
@ -28,4 +27,3 @@ nav a:hover {
|
||||||
nav a.router-link-active {
|
nav a.router-link-active {
|
||||||
color: #039be5;
|
color: #039be5;
|
||||||
}
|
}
|
||||||
/* #enddocregion css */
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { HeroService } from './hero.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-app',
|
selector: 'my-app',
|
||||||
// #docregion template
|
// #docregion template
|
||||||
template: `
|
template: `
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
<nav>
|
<nav>
|
||||||
|
@ -21,10 +21,10 @@ import { HeroService } from './hero.service';
|
||||||
</nav>
|
</nav>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
`,
|
`,
|
||||||
// #enddocregion template
|
// #enddocregion template
|
||||||
// #docregion style-urls
|
// #docregion style-urls
|
||||||
styleUrls: ['app/app.component.css'],
|
styleUrls: ['app/app.component.css'],
|
||||||
// #enddocregion style-urls
|
// #enddocregion style-urls
|
||||||
directives: [ROUTER_DIRECTIVES],
|
directives: [ROUTER_DIRECTIVES],
|
||||||
providers: [
|
providers: [
|
||||||
ROUTER_PROVIDERS,
|
ROUTER_PROVIDERS,
|
||||||
|
@ -32,21 +32,21 @@ import { HeroService } from './hero.service';
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@RouteConfig([
|
@RouteConfig([
|
||||||
// #docregion dashboard-route
|
// #docregion dashboard-route
|
||||||
{
|
{
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
component: DashboardComponent,
|
component: DashboardComponent,
|
||||||
useAsDefault: true
|
useAsDefault: true
|
||||||
},
|
},
|
||||||
// #enddocregion dashboard-route
|
// #enddocregion dashboard-route
|
||||||
// #docregion hero-detail-route
|
// #docregion hero-detail-route
|
||||||
{
|
{
|
||||||
path: '/detail/:id',
|
path: '/detail/:id',
|
||||||
name: 'HeroDetail',
|
name: 'HeroDetail',
|
||||||
component: HeroDetailComponent
|
component: HeroDetailComponent
|
||||||
},
|
},
|
||||||
// #enddocregion hero-detail-route
|
// #enddocregion hero-detail-route
|
||||||
{
|
{
|
||||||
path: '/heroes',
|
path: '/heroes',
|
||||||
name: 'Heroes',
|
name: 'Heroes',
|
||||||
|
@ -56,4 +56,3 @@ import { HeroService } from './hero.service';
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'Tour of Heroes';
|
title = 'Tour of Heroes';
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -24,4 +24,3 @@ export class DashboardComponent implements OnInit {
|
||||||
|
|
||||||
gotoDetail() { /* not implemented yet */}
|
gotoDetail() { /* not implemented yet */}
|
||||||
}
|
}
|
||||||
// #enddocregion component
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
/* #docplaster */
|
|
||||||
/* #docregion */
|
/* #docregion */
|
||||||
[class*='col-'] {
|
[class*='col-'] {
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -60,4 +59,3 @@ h4 {
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* #enddocregion */
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<!-- #docregion -->
|
<!-- #docregion -->
|
||||||
<h3>Top Heroes</h3>
|
<h3>Top Heroes</h3>
|
||||||
<div class="grid grid-pad">
|
<div class="grid grid-pad">
|
||||||
<!-- #docregion click -->
|
<!-- #docregion click -->
|
||||||
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4">
|
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1-4">
|
||||||
<!-- #enddocregion click -->
|
<!-- #enddocregion click -->
|
||||||
<div class="module hero">
|
<div class="module hero">
|
||||||
<h4>{{hero.name}}</h4>
|
<h4>{{hero.name}}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,12 +22,12 @@ export class DashboardComponent implements OnInit {
|
||||||
|
|
||||||
heroes: Hero[] = [];
|
heroes: Hero[] = [];
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private heroService: HeroService) {
|
private heroService: HeroService) {
|
||||||
}
|
}
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.heroService.getHeroes()
|
this.heroService.getHeroes()
|
||||||
|
@ -41,4 +41,3 @@ export class DashboardComponent implements OnInit {
|
||||||
}
|
}
|
||||||
// #enddocregion goto-detail
|
// #enddocregion goto-detail
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
// #docregion v2
|
// #docregion import-oninit, v2
|
||||||
// #docregion import-oninit
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
// #enddocregion import-oninit
|
// #enddocregion import-oninit
|
||||||
// #docregion import-route-params
|
// #docregion import-route-params
|
||||||
|
@ -18,25 +17,24 @@ import { HeroService } from './hero.service';
|
||||||
selector: 'my-hero-detail',
|
selector: 'my-hero-detail',
|
||||||
// #docregion template-url
|
// #docregion template-url
|
||||||
templateUrl: 'app/hero-detail.component.html',
|
templateUrl: 'app/hero-detail.component.html',
|
||||||
// #enddocregion template-url
|
// #enddocregion template-url, v2
|
||||||
// #enddocregion v2
|
|
||||||
styleUrls: ['app/hero-detail.component.css']
|
styleUrls: ['app/hero-detail.component.css']
|
||||||
// #docregion v2
|
// #docregion v2
|
||||||
})
|
})
|
||||||
// #enddocregion extract-template
|
// #enddocregion extract-template
|
||||||
// #docregion implement
|
// #docregion implement
|
||||||
export class HeroDetailComponent implements OnInit {
|
export class HeroDetailComponent implements OnInit {
|
||||||
// #enddocregion implement
|
// #enddocregion implement
|
||||||
hero: Hero;
|
hero: Hero;
|
||||||
|
|
||||||
// #docregion ctor
|
// #docregion ctor
|
||||||
constructor(
|
constructor(
|
||||||
private heroService: HeroService,
|
private heroService: HeroService,
|
||||||
private routeParams: RouteParams) {
|
private routeParams: RouteParams) {
|
||||||
}
|
}
|
||||||
// #enddocregion ctor
|
// #enddocregion ctor
|
||||||
|
|
||||||
// #docregion ng-oninit
|
// #docregion ng-oninit
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
// #docregion get-id
|
// #docregion get-id
|
||||||
let id = +this.routeParams.get('id');
|
let id = +this.routeParams.get('id');
|
||||||
|
@ -44,13 +42,11 @@ export class HeroDetailComponent implements OnInit {
|
||||||
this.heroService.getHero(id)
|
this.heroService.getHero(id)
|
||||||
.then(hero => this.hero = hero);
|
.then(hero => this.hero = hero);
|
||||||
}
|
}
|
||||||
// #enddocregion ng-oninit
|
// #enddocregion ng-oninit
|
||||||
|
|
||||||
// #docregion go-back
|
// #docregion go-back
|
||||||
goBack() {
|
goBack() {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
}
|
}
|
||||||
// #enddocregion go-back
|
// #enddocregion go-back
|
||||||
}
|
}
|
||||||
// #enddocregion v2
|
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -24,4 +24,3 @@ export class HeroService {
|
||||||
}
|
}
|
||||||
// #enddocregion get-hero
|
// #enddocregion get-hero
|
||||||
}
|
}
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -17,5 +17,3 @@
|
||||||
</h2>
|
</h2>
|
||||||
<button (click)="gotoDetail()">View Details</button>
|
<button (click)="gotoDetail()">View Details</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- #enddocregion mini-detail -->
|
|
||||||
<!-- #enddocregion -->
|
|
||||||
|
|
|
@ -6,21 +6,18 @@ import { Router } from '@angular/router-deprecated';
|
||||||
import { Hero } from './hero';
|
import { Hero } from './hero';
|
||||||
import { HeroService } from './hero.service';
|
import { HeroService } from './hero.service';
|
||||||
|
|
||||||
// #docregion metadata
|
// #docregion heroes-component-renaming, metadata
|
||||||
// #docregion heroes-component-renaming
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-heroes',
|
selector: 'my-heroes',
|
||||||
// #enddocregion heroes-component-renaming
|
// #enddocregion heroes-component-renaming
|
||||||
templateUrl: 'app/heroes.component.html',
|
templateUrl: 'app/heroes.component.html',
|
||||||
styleUrls: ['app/heroes.component.css']
|
styleUrls: ['app/heroes.component.css']
|
||||||
// #docregion heroes-component-renaming
|
// #docregion heroes-component-renaming
|
||||||
})
|
})
|
||||||
// #enddocregion heroes-component-renaming
|
// #enddocregion heroes-component-renaming, metadata
|
||||||
// #enddocregion metadata
|
// #docregion class, heroes-component-renaming
|
||||||
// #docregion class
|
|
||||||
// #docregion heroes-component-renaming
|
|
||||||
export class HeroesComponent implements OnInit {
|
export class HeroesComponent implements OnInit {
|
||||||
// #enddocregion heroes-component-renaming
|
// #enddocregion heroes-component-renaming
|
||||||
heroes: Hero[];
|
heroes: Hero[];
|
||||||
selectedHero: Hero;
|
selectedHero: Hero;
|
||||||
|
|
||||||
|
@ -41,8 +38,5 @@ export class HeroesComponent implements OnInit {
|
||||||
gotoDetail() {
|
gotoDetail() {
|
||||||
this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
|
this.router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
|
||||||
}
|
}
|
||||||
// #docregion heroes-component-renaming
|
// #docregion heroes-component-renaming
|
||||||
}
|
}
|
||||||
// #enddocregion heroes-component-renaming
|
|
||||||
// #enddocregion class
|
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -13,4 +13,3 @@ export var HEROES: Hero[] = [
|
||||||
{id: 19, name: 'Magma'},
|
{id: 19, name: 'Magma'},
|
||||||
{id: 20, name: 'Tornado'}
|
{id: 20, name: 'Tornado'}
|
||||||
];
|
];
|
||||||
// #enddocregion
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<!-- #docregion head -->
|
<!-- #docregion head -->
|
||||||
<!-- #docregion base-href -->
|
<!-- #docregion base-href -->
|
||||||
<head>
|
<head>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<!-- #enddocregion base-href -->
|
<!-- #enddocregion base-href -->
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
/* #docregion */
|
/* #docregion toh-excerpt */
|
||||||
h2 {
|
/* Master Styles */
|
||||||
|
h1 {
|
||||||
|
color: #369;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 250%;
|
||||||
|
}
|
||||||
|
h2, h3 {
|
||||||
color: #444;
|
color: #444;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
|
@ -11,23 +17,7 @@ body, input[text], button {
|
||||||
color: #888;
|
color: #888;
|
||||||
font-family: Cambria, Georgia;
|
font-family: Cambria, Georgia;
|
||||||
}
|
}
|
||||||
button {
|
/* . . . */
|
||||||
font-family: Arial;
|
|
||||||
background-color: #eee;
|
|
||||||
border: none;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
cursor: hand;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
background-color: #cfd8dc;
|
|
||||||
}
|
|
||||||
button:disabled {
|
|
||||||
background-color: #eee;
|
|
||||||
color: #aaa;
|
|
||||||
cursor: auto;
|
|
||||||
}
|
|
||||||
/* everywhere else */
|
/* everywhere else */
|
||||||
* {
|
* {
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
|
|
@ -3,10 +3,10 @@ include ../_util-fns
|
||||||
:marked
|
:marked
|
||||||
# Routing Around the App
|
# Routing Around the App
|
||||||
We received new requirements for our Tour of Heroes application:
|
We received new requirements for our Tour of Heroes application:
|
||||||
* add a *Dashboard* view.
|
* Add a *Dashboard* view.
|
||||||
* navigate between the *Heroes* and *Dashboard* views.
|
* Navigate between the *Heroes* and *Dashboard* views.
|
||||||
* clicking on a hero in either view navigates to a detail view of the selected hero.
|
* Clicking on a hero in either view navigates to a detail view of the selected hero.
|
||||||
* clicking a *deep link* in an email opens the detail view for a particular hero;
|
* Clicking a *deep link* in an email opens the detail view for a particular hero;
|
||||||
|
|
||||||
When we’re done, users will be able to navigate the app like this:
|
When we’re done, users will be able to navigate the app like this:
|
||||||
figure.image-display
|
figure.image-display
|
||||||
|
@ -16,7 +16,7 @@ figure.image-display
|
||||||
.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-deprecated.html) chapter covers the router in more detail
|
||||||
than we will in this tour.
|
than we will in this tutorial.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
|
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
|
||||||
|
|
||||||
|
@ -65,10 +65,10 @@ code-example(language="bash").
|
||||||
## Action plan
|
## Action plan
|
||||||
Here's our plan
|
Here's our plan
|
||||||
|
|
||||||
* turn `AppComponent` into an application shell that only handles navigation.
|
* turn `AppComponent` into an application shell that only handles navigation,
|
||||||
* relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
|
* relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`,
|
||||||
* add routing
|
* add routing,
|
||||||
* create a new `DashboardComponent`
|
* create a new `DashboardComponent`,
|
||||||
* tie the *Dashboard* into the navigation structure.
|
* tie the *Dashboard* into the navigation structure.
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
|
@ -91,13 +91,13 @@ code-example(language="bash").
|
||||||
Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent`
|
Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent`
|
||||||
and create a new `AppComponent` shell separately.
|
and create a new `AppComponent` shell separately.
|
||||||
|
|
||||||
The steps are:
|
The steps are: rename the
|
||||||
* rename `app.component.ts` file to `heroes.component.ts`.
|
* `app.component.ts` file to `heroes.component.ts`,
|
||||||
* rename the `AppComponent` class to `HeroesComponent`.
|
* `AppComponent` class to `HeroesComponent`,
|
||||||
* rename the selector `my-app` to `my-heroes`.
|
* selector `my-app` to `my-heroes`.
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (renaming)')(format=".")
|
+makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (showing renamings only)')(format=".")
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
## Create *AppComponent*
|
## Create *AppComponent*
|
||||||
|
@ -154,10 +154,10 @@ code-example(language="bash").
|
||||||
|
|
||||||
The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`),
|
The Angular router is a combination of multiple services (`ROUTER_PROVIDERS`), multiple directives (`ROUTER_DIRECTIVES`),
|
||||||
and a configuration decorator (`RouteConfig`). We'll import them all together:
|
and a configuration decorator (`RouteConfig`). We'll import them all together:
|
||||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'import-router', 'app.component.ts (router imports)')(format=".")
|
+makeExample('toh-5/ts/app/app.component.2.ts', 'import-router', 'app/app.component.ts (router imports)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Next we update the `directives` and `providers` metadata arrays to *include* the router assets.
|
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.component.ts (directives and providers)')(format=".")
|
+makeExample('toh-5/ts/app/app.component.2.ts', 'directives-and-providers', 'app/app.component.ts (directives and providers)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Notice that we also removed the `HeroesComponent` from the `directives` array.
|
Notice that we also removed the `HeroesComponent` from the `directives` array.
|
||||||
`AppComponent` no longer shows heroes; that will be the router's job.
|
`AppComponent` no longer shows heroes; that will be the router's job.
|
||||||
|
@ -172,7 +172,7 @@ code-example(language="bash").
|
||||||
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.component.ts (RouteConfig for heroes)')(format=".")
|
+makeExample('toh-5/ts/app/app.component.2.ts', 'route-config', 'app/app.component.ts (RouteConfig for heroes)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
`@RouteConfig` takes an array of *route definitions*.
|
`@RouteConfig` takes 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.
|
||||||
|
@ -203,7 +203,7 @@ code-example(language="bash").
|
||||||
We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`.
|
We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`.
|
||||||
|
|
||||||
The revised template looks like this:
|
The revised template looks like this:
|
||||||
+makeExample('toh-5/ts/app/app.component.2.ts', 'template', 'app.component.ts (template for Heroes)')(format=".")
|
+makeExample('toh-5/ts/app/app.component.2.ts', 'template', 'app/app.component.ts (template v1)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Notice the `[routerLink]` binding in the anchor tag.
|
Notice the `[routerLink]` binding in the anchor tag.
|
||||||
We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to an array
|
We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to an array
|
||||||
|
@ -250,7 +250,7 @@ code-example(language="bash").
|
||||||
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 `@RouteConfig` array of definitions.
|
||||||
+makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app.component.ts (Dashboard Route)')(format=".")
|
+makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app/app.component.ts (Dashboard route)')(format=".")
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
**useAsDefault**
|
**useAsDefault**
|
||||||
|
@ -265,7 +265,7 @@ code-example(language="bash").
|
||||||
: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.
|
||||||
|
|
||||||
+makeExample('toh-5/ts/app/app.component.ts','template', 'app.component.ts (template)')(format=".")
|
+makeExample('toh-5/ts/app/app.component.ts','template', 'app/app.component.ts (template)')(format=".")
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
We nestled the two links within `<nav>` tags.
|
We nestled the two links within `<nav>` tags.
|
||||||
|
@ -288,7 +288,7 @@ code-example(language="bash").
|
||||||
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths.html) if we prefer.
|
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths.html) if we prefer.
|
||||||
:marked
|
:marked
|
||||||
Create that file with these contents:
|
Create that file with these contents:
|
||||||
+makeExample('toh-5/ts/app/dashboard.component.html', null, 'dashboard.component.html')(format=".")
|
+makeExample('toh-5/ts/app/dashboard.component.html', null, 'app/dashboard.component.html')(format=".")
|
||||||
:marked
|
:marked
|
||||||
We use `*ngFor` once again to iterate over a list of heroes and display their names.
|
We use `*ngFor` once again to iterate over a list of heroes and display their names.
|
||||||
We added extra `<div>` elements to help with styling later in this chapter.
|
We added extra `<div>` elements to help with styling later in this chapter.
|
||||||
|
@ -305,7 +305,7 @@ code-example(language="bash").
|
||||||
and added it to the `providers` array of the top level `AppComponent`.
|
and added it to the `providers` array of the top level `AppComponent`.
|
||||||
|
|
||||||
That move created a singleton `HeroService` instance, available to *all* components of the application.
|
That move created a singleton `HeroService` instance, available to *all* components of the application.
|
||||||
We'll inject and use it here in the `DashboardComponent` .
|
Angular will inject `HeroService` and we'll use it here in the `DashboardComponent`.
|
||||||
|
|
||||||
### Get heroes
|
### Get heroes
|
||||||
Open the `dashboard.component.ts` and add the requisite `import` statements.
|
Open the `dashboard.component.ts` and add the requisite `import` statements.
|
||||||
|
@ -364,7 +364,7 @@ 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.component.ts','hero-detail-route', 'app/app.component.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`.
|
||||||
|
@ -389,19 +389,19 @@ code-example(format='').
|
||||||
:marked
|
:marked
|
||||||
## Revise the *HeroDetailComponent*
|
## Revise the *HeroDetailComponent*
|
||||||
|
|
||||||
Before we rewrite the `HeroDetailComponent`, let's remember what it looks like now:
|
Before we rewrite the `HeroDetailComponent`, let's review what it looks like now:
|
||||||
+makeExample('toh-4/ts/app/hero-detail.component.ts', null, 'app/hero-detail.component.ts (current)')
|
+makeExample('toh-4/ts/app/hero-detail.component.ts', null, 'app/hero-detail.component.ts (current)')
|
||||||
:marked
|
:marked
|
||||||
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 router's `RouteParams` service
|
||||||
and use the `HeroService` to fetch the hero with that `id` from storage.
|
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 `RouteParams`.
|
||||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-route-params')(format=".")
|
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'import-route-params')(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` interface because we'll call the `HeroService` inside the `ngOnInit` component lifecycle hook.
|
||||||
|
@ -460,13 +460,11 @@ code-example(format='').
|
||||||
:marked
|
:marked
|
||||||
Here's the (nearly) finished `HeroDetailComponent`:
|
Here's the (nearly) finished `HeroDetailComponent`:
|
||||||
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'v2', 'app/hero-detail.component.ts (latest)')(format=".")
|
+makeExample('toh-5/ts/app/hero-detail.component.ts', 'v2', 'app/hero-detail.component.ts (latest)')(format=".")
|
||||||
:marked
|
|
||||||
|
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Select a *Dashboard* Hero
|
## Select a *Dashboard* Hero
|
||||||
When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero..
|
When a user selects a hero in the dashboard, the app should navigate to the `HeroDetailComponent` to view and edit the selected hero.
|
||||||
|
|
||||||
In the dashboard template we bound each hero's click event to the `gotoDetail` method, passing along the selected `hero` entity.
|
In the dashboard template we bound each hero's click event to the `gotoDetail` method, passing along the selected `hero` entity.
|
||||||
+makeExample('toh-5/ts/app/dashboard.component.html','click', 'app/dashboard.component.html (click binding)')(format=".")
|
+makeExample('toh-5/ts/app/dashboard.component.html','click', 'app/dashboard.component.html (click binding)')(format=".")
|
||||||
|
@ -489,7 +487,7 @@ code-example(format='').
|
||||||
+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.component.ts','hero-detail-route', 'app/app.component.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`):
|
||||||
|
|
||||||
+makeExample('toh-5/ts/app/dashboard.component.ts','import-router', 'app/dashboard.component.ts (excerpts)')(format=".")
|
+makeExample('toh-5/ts/app/dashboard.component.ts','import-router', 'app/dashboard.component.ts (excerpts)')(format=".")
|
||||||
+makeExample('toh-5/ts/app/dashboard.component.ts','ctor')(format=".")
|
+makeExample('toh-5/ts/app/dashboard.component.ts','ctor')(format=".")
|
||||||
|
@ -526,7 +524,7 @@ figure.image-display
|
||||||
### Format with the *UpperCasePipe*
|
### Format with the *UpperCasePipe*
|
||||||
|
|
||||||
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `UpperCasePipe`
|
Notice that the hero's name is displayed in CAPITAL LETTERS. That's the effect of the `UpperCasePipe`
|
||||||
that we slipped into the interpolation binding. Look for it right after the pipe operator, ( | ).
|
that we slipped into the interpolation binding. Look for it right after the pipe operator ( | ).
|
||||||
+makeExample('toh-5/ts/app/heroes.component.html','pipe')(format=".")
|
+makeExample('toh-5/ts/app/heroes.component.html','pipe')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Pipes are a good way to format strings, currency amounts, dates and other display data.
|
Pipes are a good way to format strings, currency amounts, dates and other display data.
|
||||||
|
@ -551,14 +549,14 @@ figure.image-display
|
||||||
So we can remove it from the metadata `directives` array. The `directives` array is now empty so we delete it.
|
So we can remove it from the metadata `directives` array. The `directives` array is now empty so we delete it.
|
||||||
We might as well delete the `HeroDetailComponent` import statement too.
|
We might as well delete the `HeroDetailComponent` import statement too.
|
||||||
|
|
||||||
The revised component metadata looks like this:
|
The revised `@Component` looks like this:
|
||||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'metadata', 'app/heroes.component.ts (revised metadata)')(format=".")
|
+makeExample('toh-5/ts/app/heroes.component.ts', 'metadata', 'app/heroes.component.ts (revised metadata)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
Now we can see what's going on as we update the component class along the same lines as the dashboard:
|
||||||
1. Import the `router`
|
1. Import the `router`
|
||||||
1. Inject the `router` in the constructor (along with the `HeroService`)
|
1. Inject the `router` in the constructor (along with the `HeroService`)
|
||||||
1. Implement the `gotoDetail` method by calling the `router.navigate` method
|
1. Implement the `gotoDetail` method by calling the `router.navigate` method
|
||||||
with a two-part 'HeroDetail' *link parameters array*.
|
with a two-part `HeroDetail` *link parameters array*.
|
||||||
|
|
||||||
Here's the revised component class:
|
Here's the revised component class:
|
||||||
+makeExample('toh-5/ts/app/heroes.component.ts', 'class', 'app/heroes.component.ts (class)')
|
+makeExample('toh-5/ts/app/heroes.component.ts', 'class', 'app/heroes.component.ts (class)')
|
||||||
|
@ -613,7 +611,7 @@ figure.image-display
|
||||||
We cooperated by surrounding those links in `<nav>` tags.
|
We cooperated by surrounding those links in `<nav>` tags.
|
||||||
|
|
||||||
Add a `app.component.css` file to the `app` folder with the following content.
|
Add a `app.component.css` file to the `app` folder with the following content.
|
||||||
+makeExample('toh-5/ts/app/app.component.css', '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 *router-link-active* class**
|
||||||
|
@ -631,12 +629,21 @@ figure.image-display
|
||||||
|
|
||||||
We can also create styles at the *application level* outside of any component.
|
We can also create styles at the *application level* outside of any component.
|
||||||
|
|
||||||
Our designers provided some basic styles to apply to elements across the entire app.
|
Our designers provided some basic styles to apply to elements across the entire app.
|
||||||
Add the following to a new file named `styles.css` in the root folder.
|
These correspond to the full set of master styles that we
|
||||||
+makeExample('toh-5/ts/styles.1.css', '', 'styles.css (App Styles)')(format=".")
|
introduced earlier (see
|
||||||
|
[QuickStart, "Add some style"](../quickstart.html#!#add-some-style)).
|
||||||
|
Here is an excerpt.
|
||||||
|
|
||||||
|
+makeExample('toh-5/ts/styles.1.css', 'toh-excerpt', 'styles.css (app styles excerpt)')(format=".")
|
||||||
|
|
||||||
|
- var styles_css = 'https://raw.githubusercontent.com/angular/angular.io/master/public/docs/_examples/styles.css'
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Reference this stylesheet within the `index.html` in the traditional manner.
|
Add a new file named `styles.css` in the root folder, if there isn't one already.
|
||||||
|
Ensure that it contains the [master styles given here](!{styles_css}).
|
||||||
|
|
||||||
|
Also ensure this stylesheet is referenced in the traditional manner within `index.html`.
|
||||||
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
+makeExample('toh-5/ts/index.html','css', 'index.html (link ref)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
Look at the app now. Our dashboard, heroes, and navigation links are styling!
|
Look at the app now. Our dashboard, heroes, and navigation links are styling!
|
||||||
|
@ -680,7 +687,6 @@ p.
|
||||||
.file systemjs.config.json
|
.file systemjs.config.json
|
||||||
.file tsconfig.json
|
.file tsconfig.json
|
||||||
.file typings.json
|
.file typings.json
|
||||||
:marked
|
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -689,15 +695,15 @@ p.
|
||||||
### The Road Behind
|
### The Road Behind
|
||||||
We travelled a great distance in this chapter.
|
We travelled a great distance in this chapter.
|
||||||
- We added the Angular *Component Router* to navigate among different components.
|
- We added the Angular *Component Router* to navigate among different components.
|
||||||
- We learned how to create router links to represent navigation menu items
|
- We learned how to create router links to represent navigation menu items.
|
||||||
- We used router parameters to navigate to the details of user selected hero
|
- We used router parameters to navigate to the details of user selected hero.
|
||||||
- We shared the `HeroService` among multiple components
|
- We shared the `HeroService` among multiple components.
|
||||||
- We moved HTML and CSS out of the component file and into their own files.
|
- We moved HTML and CSS out of the component file and into their own files.
|
||||||
- We added the `uppercase` pipe to format data
|
- We added the `uppercase` pipe to format data.
|
||||||
|
|
||||||
### The Road Ahead
|
### The Road Ahead
|
||||||
We have much of the foundation we need to build an application.
|
We have much of the foundation we need to build an application.
|
||||||
We're still missing a key piece: remote data access.
|
We're still missing a key piece: remote data access.
|
||||||
|
|
||||||
In a forthcoming tutorial chapter,
|
In the next chapter,
|
||||||
we’ll replace our mock data with data retrieved from a server using http.
|
we’ll replace our mock data with data retrieved from a server using http.
|
||||||
|
|
Loading…
Reference in New Issue