+
+ {{selectedHero.name | uppercase}} is my hero
+
+
+
+
+
+
diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.js b/public/docs/_examples/toh-5/ts/app/heroes.component.js
new file mode 100644
index 0000000000..9ba5693e11
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/heroes.component.js
@@ -0,0 +1,65 @@
+System.register(['angular2/core', 'angular2/router', './hero-detail.component', './hero.service'], function(exports_1) {
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
+ };
+ var __metadata = (this && this.__metadata) || function (k, v) {
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
+ };
+ var core_1, router_1, hero_detail_component_1, hero_service_1;
+ var HeroesComponent;
+ return {
+ setters:[
+ function (core_1_1) {
+ core_1 = core_1_1;
+ },
+ function (router_1_1) {
+ router_1 = router_1_1;
+ },
+ function (hero_detail_component_1_1) {
+ hero_detail_component_1 = hero_detail_component_1_1;
+ },
+ function (hero_service_1_1) {
+ hero_service_1 = hero_service_1_1;
+ }],
+ execute: function() {
+ // #docregion metadata
+ // #docregion heroes-component-renaming
+ HeroesComponent = (function () {
+ function HeroesComponent(_router, _heroService) {
+ this._router = _router;
+ this._heroService = _heroService;
+ }
+ HeroesComponent.prototype.getHeroes = function () {
+ var _this = this;
+ this._heroService.getHeroes().then(function (heroes) { return _this.heroes = heroes; });
+ };
+ HeroesComponent.prototype.ngOnInit = function () {
+ this.getHeroes();
+ };
+ HeroesComponent.prototype.onSelect = function (hero) { this.selectedHero = hero; };
+ HeroesComponent.prototype.gotoDetail = function () {
+ this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
+ };
+ HeroesComponent = __decorate([
+ core_1.Component({
+ selector: 'my-heroes',
+ // #enddocregion heroes-component-renaming
+ templateUrl: 'app/heroes.component.html',
+ styleUrls: ['app/heroes.component.css'],
+ directives: [hero_detail_component_1.HeroDetailComponent]
+ }),
+ __metadata('design:paramtypes', [router_1.Router, hero_service_1.HeroService])
+ ], HeroesComponent);
+ return HeroesComponent;
+ })();
+ exports_1("HeroesComponent", HeroesComponent);
+ }
+ }
+});
+// #enddocregion heroes-component-renaming
+// #enddocregion class
+// #enddocregion
+//# sourceMappingURL=heroes.component.js.map
\ No newline at end of file
diff --git a/public/docs/_examples/toh-5/ts/app/heroes.component.ts b/public/docs/_examples/toh-5/ts/app/heroes.component.ts
new file mode 100644
index 0000000000..6cdb00bc83
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/heroes.component.ts
@@ -0,0 +1,50 @@
+// #docplaster
+// #docregion
+import { Component, OnInit } from 'angular2/core';
+import { Router } from 'angular2/router';
+
+import { Hero } from './hero';
+import { HeroDetailComponent } from './hero-detail.component';
+import { HeroService } from './hero.service';
+
+// #docregion metadata
+// #docregion heroes-component-renaming
+@Component({
+ selector: 'my-heroes',
+// #enddocregion heroes-component-renaming
+ templateUrl: 'app/heroes.component.html',
+ styleUrls: ['app/heroes.component.css'],
+ directives: [HeroDetailComponent]
+// #docregion heroes-component-renaming
+})
+// #enddocregion heroes-component-renaming
+// #enddocregion metadata
+// #docregion class
+// #docregion heroes-component-renaming
+export class HeroesComponent implements OnInit {
+// #enddocregion heroes-component-renaming
+ heroes: Hero[];
+ selectedHero: Hero;
+
+ constructor(
+ private _router: Router,
+ private _heroService: HeroService) { }
+
+ getHeroes() {
+ this._heroService.getHeroes().then(heroes => this.heroes = heroes);
+ }
+
+ ngOnInit() {
+ this.getHeroes();
+ }
+
+ onSelect(hero: Hero) { this.selectedHero = hero; }
+
+ gotoDetail() {
+ this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
+ }
+// #docregion heroes-component-renaming
+}
+// #enddocregion heroes-component-renaming
+// #enddocregion class
+// #enddocregion
\ No newline at end of file
diff --git a/public/docs/_examples/toh-5/ts/app/main.js b/public/docs/_examples/toh-5/ts/app/main.js
new file mode 100644
index 0000000000..da70522909
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/main.js
@@ -0,0 +1,16 @@
+System.register(['angular2/platform/browser', './app.component'], function(exports_1) {
+ var browser_1, app_component_1;
+ return {
+ setters:[
+ function (browser_1_1) {
+ browser_1 = browser_1_1;
+ },
+ function (app_component_1_1) {
+ app_component_1 = app_component_1_1;
+ }],
+ execute: function() {
+ browser_1.bootstrap(app_component_1.AppComponent);
+ }
+ }
+});
+//# sourceMappingURL=main.js.map
\ No newline at end of file
diff --git a/public/docs/_examples/toh-5/ts/app/main.ts b/public/docs/_examples/toh-5/ts/app/main.ts
new file mode 100644
index 0000000000..c469e18fd0
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/main.ts
@@ -0,0 +1,4 @@
+import { bootstrap } from 'angular2/platform/browser';
+import { AppComponent } from './app.component';
+
+bootstrap(AppComponent);
\ No newline at end of file
diff --git a/public/docs/_examples/toh-5/ts/app/mock-heroes.js b/public/docs/_examples/toh-5/ts/app/mock-heroes.js
new file mode 100644
index 0000000000..5c4882e9a4
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/mock-heroes.js
@@ -0,0 +1,22 @@
+System.register([], function(exports_1) {
+ var HEROES;
+ return {
+ setters:[],
+ execute: function() {
+ exports_1("HEROES", HEROES = [
+ { "id": 11, "name": "Mr. Nice" },
+ { "id": 12, "name": "Narco" },
+ { "id": 13, "name": "Bombasto" },
+ { "id": 14, "name": "Celeritas" },
+ { "id": 15, "name": "Magneta" },
+ { "id": 16, "name": "RubberMan" },
+ { "id": 17, "name": "Dynama" },
+ { "id": 18, "name": "Dr IQ" },
+ { "id": 19, "name": "Magma" },
+ { "id": 20, "name": "Tornado" }
+ ]);
+ }
+ }
+});
+// #enddocregion
+//# sourceMappingURL=mock-heroes.js.map
\ No newline at end of file
diff --git a/public/docs/_examples/toh-5/ts/app/mock-heroes.ts b/public/docs/_examples/toh-5/ts/app/mock-heroes.ts
new file mode 100644
index 0000000000..cdcba35097
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/app/mock-heroes.ts
@@ -0,0 +1,16 @@
+// #docregion
+import { Hero } from './hero';
+
+export var HEROES: Hero[] = [
+ {"id": 11, "name": "Mr. Nice"},
+ {"id": 12, "name": "Narco"},
+ {"id": 13, "name": "Bombasto"},
+ {"id": 14, "name": "Celeritas"},
+ {"id": 15, "name": "Magneta"},
+ {"id": 16, "name": "RubberMan"},
+ {"id": 17, "name": "Dynama"},
+ {"id": 18, "name": "Dr IQ"},
+ {"id": 19, "name": "Magma"},
+ {"id": 20, "name": "Tornado"}
+];
+// #enddocregion
\ No newline at end of file
diff --git a/public/docs/_examples/toh-5/ts/index.html b/public/docs/_examples/toh-5/ts/index.html
new file mode 100644
index 0000000000..821ef1a586
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/index.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+ Angular 2 Tour of Heroes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading...
+
+
diff --git a/public/docs/_examples/toh-5/ts/plnkr.json b/public/docs/_examples/toh-5/ts/plnkr.json
new file mode 100644
index 0000000000..019630c28f
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/plnkr.json
@@ -0,0 +1,9 @@
+{
+ "description": "Tour of Heroes: Part 5",
+ "files":[
+ "!**/*.d.ts",
+ "!**/*.js",
+ "!**/*.[1,2].*"
+ ],
+ "tags": ["tutorial", "tour", "heroes", "router"]
+}
diff --git a/public/docs/_examples/toh-5/ts/styles.css b/public/docs/_examples/toh-5/ts/styles.css
new file mode 100644
index 0000000000..88ec8391d3
--- /dev/null
+++ b/public/docs/_examples/toh-5/ts/styles.css
@@ -0,0 +1,7 @@
+/* #docplaster */
+/* #docregion */
+h2 { color: #444; font-weight: lighter; }
+body { margin: 2em; }
+body, input[text], button { color: #888; font-family: Cambria, Georgia; }
+button { padding: 0.2em; font-size: 14px}
+* { font-family: Arial; }
diff --git a/public/docs/_examples/tutorial/ts/app/dashboard.component.ts b/public/docs/_examples/tutorial/ts/app/dashboard.component.ts
index 62bf854264..ae5f048a57 100644
--- a/public/docs/_examples/tutorial/ts/app/dashboard.component.ts
+++ b/public/docs/_examples/tutorial/ts/app/dashboard.component.ts
@@ -18,6 +18,7 @@ export class DashboardComponent implements OnInit {
}
gotoDetail(hero: Hero) {
- this._router.navigate(['HeroDetail', { id: hero.id }]);
+ let link = ['HeroDetail', { id: hero.id }];
+ this._router.navigate(link);
}
}
diff --git a/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts b/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts
index 5540704913..0014918b8b 100644
--- a/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts
+++ b/public/docs/_examples/tutorial/ts/app/hero-detail.component.ts
@@ -1,5 +1,6 @@
import {Component, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';
+
import {Hero} from './hero';
import {HeroService} from './hero.service';
@@ -17,10 +18,8 @@ export class HeroDetailComponent implements OnInit {
}
ngOnInit() {
- if (!this.hero) {
- let id = +this._routeParams.get('id');
- this._heroService.getHero(id).then(hero => this.hero = hero);
- }
+ let id = +this._routeParams.get('id');
+ this._heroService.getHero(id).then(hero => this.hero = hero);
}
goBack() {
diff --git a/public/docs/_examples/tutorial/ts/app/hero.service.ts b/public/docs/_examples/tutorial/ts/app/hero.service.ts
index 45b4e25adf..c3d6bc0cee 100644
--- a/public/docs/_examples/tutorial/ts/app/hero.service.ts
+++ b/public/docs/_examples/tutorial/ts/app/hero.service.ts
@@ -1,14 +1,15 @@
import {Injectable} from 'angular2/core';
-import {HEROES} from './mock-heroes';
+import {HEROES} from './mock-heroes';
@Injectable()
export class HeroService {
- getHeroes() {
- return Promise.resolve(HEROES);
- }
+ getHeroes() {
+ return Promise.resolve(HEROES);
+ }
getHero(id: number) {
- return Promise.resolve(HEROES)
- .then(heroes => heroes.filter(h => h.id === id)[0]);
- }
+ return Promise.resolve(HEROES).then(
+ heroes => heroes.filter(hero => hero.id === id)[0]
+ );
+ }
}
diff --git a/public/docs/ts/latest/guide/router.jade b/public/docs/ts/latest/guide/router.jade
index 40536e4050..09c8ac4ae3 100644
--- a/public/docs/ts/latest/guide/router.jade
+++ b/public/docs/ts/latest/guide/router.jade
@@ -38,7 +38,13 @@ include ../../../../_includes/_util-fns
up to a modular, multi-view design with child routes.
Try that [live final version](/resources/live-examples/router/ts/plnkr.html).
-
+.l-sub-section
+ :marked
+ In plunker, to see routing changes in the browser address bar,
+ pop out the preview window by clicking this blue button in the upper right corner:
+
+
+:marked
But first, an overview of router basics.
.l-main-section
diff --git a/public/docs/ts/latest/guide/server-communication.jade b/public/docs/ts/latest/guide/server-communication.jade
index 479f4a7d94..2eed334a1f 100644
--- a/public/docs/ts/latest/guide/server-communication.jade
+++ b/public/docs/ts/latest/guide/server-communication.jade
@@ -204,7 +204,8 @@ figure.image-display
We shouldn't expect `json()` to return the heroes array directly.
The server we're calling always wraps JSON results in an object with a `data`
property. We have to unwrap it to get the heroes.
- This is conventional web api behavior, driven by security concerns.
+ This is conventional web api behavior, driven by
+ [security concerns](https://www.owasp.org/index.php/OWASP_AJAX_Security_Guidelines#Always_return_JSON_with_an_Object_on_the_outside).
:marked
### Do not return the response object
Our `getHeroes()` could have returned the `Observable`.
diff --git a/public/docs/ts/latest/tutorial/_data.json b/public/docs/ts/latest/tutorial/_data.json
index d127c8f089..e70d5aaa55 100644
--- a/public/docs/ts/latest/tutorial/_data.json
+++ b/public/docs/ts/latest/tutorial/_data.json
@@ -20,5 +20,9 @@
"toh-pt4": {
"title": "Services",
"intro": "We create a reusable service to manage our hero data calls"
+ },
+ "toh-pt5": {
+ "title": "Routing",
+ "intro": "We add the Angular Component Router and learn to navigate among the views"
}
}
\ No newline at end of file
diff --git a/public/docs/ts/latest/tutorial/toh-pt4.jade b/public/docs/ts/latest/tutorial/toh-pt4.jade
index de47528fd2..daffd1b6bc 100644
--- a/public/docs/ts/latest/tutorial/toh-pt4.jade
+++ b/public/docs/ts/latest/tutorial/toh-pt4.jade
@@ -110,7 +110,7 @@ code-example(format="." language="bash").
We already have mock `Hero` data sitting in the `AppComponent`. It doesn't belong there. It doesn't belong *here* either.
We'll move the mock data to its own file.
- Cut the the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`.
+ Cut the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`.
We copy the `import {Hero} ...` statement as well because the heroes array uses the `Hero` interface.
+makeExample('toh-4/ts/app/mock-heroes.ts', null, 'mock-heroes.ts (Heroes array)')
diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade
new file mode 100644
index 0000000000..e0ee08e1a5
--- /dev/null
+++ b/public/docs/ts/latest/tutorial/toh-pt5.jade
@@ -0,0 +1,686 @@
+include ../../../../_includes/_util-fns
+
+:marked
+ # Routing Around the App
+ We received new requirements for our Tour of Heroes application:
+ * add a *Dashboard* view.
+ * navigate between the *Heroes* and *Dashboard* views.
+ * 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;
+
+ When we’re done, users will be able to navigate the app like this:
+figure.image-display
+ img(src='/resources/images/devguide/toh/nav-diagram.png' alt="View navigations")
+:marked
+ We'll add Angular’s *Component Router* to our app to satisfy these requirements.
+.l-sub-section
+ :marked
+ The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
+ than we will in this tour.
+:marked
+ [Run the live example](/resources/live-examples/toh-5/ts/plnkr.html).
+.l-sub-section
+ :marked
+ In plunker, to see routing changes in the browser address bar,
+ pop out the preview window by clicking this blue button in the upper right corner:
+
+
+
+.l-main-section
+:marked
+ ## Where We Left Off
+ Before we continue with our Tour of Heroes, let’s verify that we have the following structure after adding our hero service
+ and hero detail component. If not, we’ll need to go back and follow the previous chapters.
+
+.filetree
+ .file angular2-tour-of-heroes
+ .children
+ .file node_modules
+ .file app
+ .children
+ .file app.component.ts
+ .file hero.ts
+ .file hero-detail.component.ts
+ .file hero.service.ts
+ .file main.ts
+ .file mock-heroes.ts
+ .file index.html
+ .file package.json
+ .file tsconfig.json
+:marked
+ ### Keep the app transpiling and running
+ Open a terminal/console window and enter the following command to
+ start the TypeScript compiler, start the server, and watch for changes:
+
+code-example(format="." language="bash").
+ npm start
+
+:marked
+ The application runs and updates automatically as we continue to build the Tour of Heroes.
+
+ ## Action plan
+ Here's our plan
+
+ * turn `AppComponent` into an application shell that only handles navigation.
+ * relocate the *Heroes* concerns within the current `AppComponent` to a separate `HeroesComponent`
+ * add routing
+ * create a new `DashboardComponent`
+ * tie the *Dashboard* into the navigation structure.
+
+.l-sub-section
+ :marked
+ *Routing* is another name for *navigation*. The *router* is the mechanism for navigating from view to view.
+
+.l-main-section
+:marked
+ ## Splitting the *AppComponent*
+
+ Our current app loads `AppComponent` and immediately displays the list of heroes.
+
+ Our revised app should present a shell with a choice of views (*Dashboard* and *Heroes*) and then default to one of them.
+
+ The `AppComponent` should only handle navigation.
+ Let's move the display of *Heroes* out of `AppComponent` and into its own `HeroesComponent`.
+
+ ### *HeroesComponent*
+ `AppComponent` is already dedicated to *Heroes*.
+ Instead of moving anything out of `AppComponent`, we'll just rename it `HeroesComponent`
+ and create a new `AppComponent` shell separately.
+
+ The steps are:
+ * rename `app.component.ts` file to `heroes.component.ts`.
+ * rename the `AppComponent` class to `HeroesComponent`.
+ * rename the selector `my-app` to `my-heroes`.
+
+:marked
++makeExample('toh-5/ts/app/heroes.component.ts', 'heroes-component-renaming', 'app/heroes.component.ts (renaming)')(format=".")
+
+:marked
+ ## Create *AppComponent*
+ The new `AppComponent` will be the application shell.
+ It will have some navigation links at the top and a display area below for the pages we navigate to.
+
+ The initial steps are:
+
+ * create a new file named `app.component.ts`.
+ * define an `AppComponent` class.
+ * `export` it so we can reference it during bootstrapping in `main.ts`.
+ * expose an application `title` property.
+ * add the `@Component` metadata decorator above the class with a `my-app` selector.
+ * add a template with `
` tags surrounding a binding to the `title` property.
+ * add the `` tags to the template so we still see the heroes.
+ * add the `HeroesComponent` to the `directives` array so Angular recognizes the `` tags.
+ * add the `HeroService` to the `providers` array because we'll need it in every other view.
+ * add the supporting `import` statements.
+
+ Our first draft looks like this:
++makeExample('toh-5/ts/app/app.component.1.ts', null, 'app/app.component.ts (v1)')
+:marked
+.callout.is-critical
+ header Remove HeroService from the HeroesComponent providers
+ :marked
+ Go back to the `HeroesComponent` and **remove the `HeroService`** from its `providers` array.
+ We are *promoting* this service from the `HeroesComponent` to the `AppComponent`.
+ We ***do not want two copies*** of this service at two different levels of our app.
+:marked
+ The app still runs and still displays heroes.
+ Our refactoring of `AppComponent` into a new `AppComponent` and a `HeroesComponent` worked!
+ We have done no harm.
+
+:marked
+ ## Add Routing
+
+ We're ready to take the next step.
+ Instead of displaying heroes automatically, we'd like to show them *after* the user clicks a button.
+ In other words, we'd like to navigate to the list of heroes.
+
+ We'll need the Angular *Component Router*.
+
+ ### Include the Router Library
+ Not all apps need routing which is why the Angular *Component Router* is in a separate, optional module library.
+
+ Our Tour of Heroes needs routing,
+ so we load the library in the `index.html` in a script tag immediately *after* the angular script itself.
++makeExample('toh-5/ts/index.html', 'router', 'index.html (router)')(format=".")
+:marked
+ While we're in `index.html`, we add `` at the top of the `` section.
++makeExample('toh-5/ts/index.html', 'base-href', 'index.html (base href)')(format=".")
+.callout.is-important
+ header base href is essential
+ :marked
+ See the *base href* section of the [Router](../guide/router.html#!#base-href) chapter to learn why this matters.
+:marked
+ ### Make the router available.
+ The *Component Router* is a service. Like any service, we have to import it and make it
+ 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`),
+ 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=".")
+: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.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 `` from the template too.
+
+ ### Add and configure the router
+
+ The `AppComponent` doesn't have a router yet. We'll use the `@RouteConfig` decorator to simultaneously
+ (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
+ pastes a URL into the browser address bar.
+
+ 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=".")
+:marked
+ `@RouteConfig` takes an array of *route definitions*.
+ We have only one route definition at the moment but rest assured, we'll add more.
+
+ This *route definition* has three parts:
+ * **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`).
+
+.l-sub-section
+ :marked
+ Learn more about defining routes with @RouteConfig in the [Routing](../guide/router.html) chapter.
+:marked
+ ### Router Outlet
+
+ If we paste the path, `/heroes`, into the browser address bar,
+ the router should match it to the `'Heroes'` route and display the `HeroesComponent`.
+ But where?
+
+ We have to ***tell it where*** by adding `` marker tags to the bottom of the template.
+ `RouterOutlet` is one of the `ROUTER_DIRECTIVES`.
+ The router displays each component immediately below the `` as we navigate through the application.
+
+ ### Router Links
+ We don't really expect users to paste a route URL into the address bar.
+ We add an anchor tag to the template which, when clicked, triggers navigation to the `HeroesComponent`.
+
+ The revised template looks like this:
++makeExample('toh-5/ts/app/app.component.2.ts', 'template', 'app.component.ts (template for Heroes)')(format=".")
+:marked
+ Notice the `[routerLink]` binding in the anchor tag.
+ We bind the `RouterLink` directive (another of the `ROUTER_DIRECTIVES`) to an array
+ that tells the router where to navigate when the user clicks the link.
+
+ 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.
+ Looking back at the route configuration, we confirm that `'Heroes'` is the name of the route to the `HeroesComponent`.
+.l-sub-section
+ :marked
+ Learn about the *link parameters array* in the [Routing](../guide/router.htmll#link-parameters-array) chapter.
+:marked
+ Refresh the browser. We see only the app title. We don't see the heroes list.
+.l-sub-section
+ :marked
+ The browser's address bar shows `/`.
+ The route path to `HeroesComponent` is `/heroes`, not `/`.
+ We don't have a route that matches the path `/`, so there is nothing to show.
+ That's something we'll want to fix.
+:marked
+ We click the "Heroes" navigation link, the browser bar updates to `/heroes`,
+ and now we see the list of heroes. We are navigating at last!
+
+ At this stage, our `AppComponent` looks like this.
++makeExample('toh-5/ts/app/app.component.2.ts',null, 'app/app.component.ts (v2)')
+:marked
+ The *AppComponent* is now attached to a router and displaying routed views.
+ For this reason and to distinguish it from other kinds of components,
+ we call this type of component a *Router Component*.
+
+
+:marked
+ ## Add a *Dashboard*
+ Routing only makes sense when we have multiple views. We need another view.
+
+ Create a placeholder `DashboardComponent` that gives us something to navigate to and from.
++makeExample('toh-5/ts/app/dashboard.component.1.ts',null, 'app/dashboard.component.ts (v1)')(format=".")
+:marked
+ We’ll come back and make it more useful later.
+
+ ### Configure the dashboard route
+ Go back to `app.component.ts` and teach it to navigate to the dashboard.
+
+ 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.
++makeExample('toh-5/ts/app/app.component.ts','dashboard-route', 'app.component.ts (Dashboard Route)')(format=".")
+.l-sub-section
+ :marked
+ **useAsDefault**
+
+ 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`.
+ 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.
+
+ 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
+ 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=".")
+.l-sub-section
+ :marked
+ We nestled the two links within `