2017-11-06 13:02:18 -05:00
|
|
|
|
# Routing
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-03-27 11:08:53 -04:00
|
|
|
|
There are new requirements for the Tour of Heroes app:
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
|
|
|
|
* Add a *Dashboard* view.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
* Add the ability to navigate between the *Heroes* and *Dashboard* views.
|
|
|
|
|
* When users click a hero name in either view, navigate to a detail view of the selected hero.
|
|
|
|
|
* When users click a *deep link* in an email, open the detail view for a particular hero.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-03-27 11:08:53 -04:00
|
|
|
|
When you’re done, users will be able to navigate the app like this:
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-05-09 18:53:32 -04:00
|
|
|
|
<figure>
|
2017-04-11 16:44:52 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<img src='generated/images/guide/toh/nav-diagram.png' alt="View navigations">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
</figure>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2018-02-22 11:08:07 -05:00
|
|
|
|
## Add the `AppRoutingModule`
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
An Angular best practice is to load and configure the router in a separate, top-level module
|
|
|
|
|
that is dedicated to routing and imported by the root `AppModule`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
By convention, the module class name is `AppRoutingModule` and it belongs in the `app-routing.module.ts` in the `src/app` folder.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Use the CLI to generate it.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
|
|
|
|
<code-example language="sh" class="code-shell">
|
2017-11-06 13:02:18 -05:00
|
|
|
|
ng generate module app-routing --flat --module=app
|
2017-03-31 19:57:13 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
<div class="l-sub-section">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
`--flat` puts the file in `src/app` instead of its own folder.<br>
|
|
|
|
|
`--module=app` tells the CLI to register it in the `imports` array of the `AppModule`.
|
2017-04-10 11:51:13 -04:00
|
|
|
|
</div>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The generated file looks like this:
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app-routing.module.0.ts"
|
|
|
|
|
title="src/app/app-routing.module.ts (generated)">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You generally don't declare components in a routing module so you can delete the
|
|
|
|
|
`@NgModule.declarations` array and delete `CommonModule` references too.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You'll configure the router with `Routes` in the `RouterModule`
|
|
|
|
|
so import those two symbols from the `@angular/router` library.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add an `@NgModule.exports` array with `RouterModule` in it.
|
|
|
|
|
Exporting `RouterModule` makes router directives available for use
|
|
|
|
|
in the `AppModule` components that will need them.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
`AppRoutingModule` looks like this now:
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="v1"
|
|
|
|
|
title="src/app/app-routing.module.ts (v1)">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Add routes
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
*Routes* tell the router which view to display when a user clicks a link or
|
2017-02-22 13:09:39 -05:00
|
|
|
|
pastes a URL into the browser address bar.
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
A typical Angular `Route` has two properties:
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
1. `path`: a string that matches the URL in the browser address bar.
|
|
|
|
|
1. `component`: the component that the router should create when navigating to this route.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You intend to navigate to the `HeroesComponent` when the URL is something like `localhost:4200/heroes`.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Import the `HeroesComponent` so you can reference it in a `Route`.
|
|
|
|
|
Then define an array of routes with a single `route` to that component.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="heroes-route">
|
|
|
|
|
</code-example>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Once you've finished setting up, the router will match that URL to `path: 'heroes'`
|
2017-11-16 09:17:18 -05:00
|
|
|
|
and display the `HeroesComponent`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### _RouterModule.forRoot()_
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You first must initialize the router and start it listening for browser location changes.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add `RouterModule` to the `@NgModule.imports` array and
|
|
|
|
|
configure it with the `routes` in one step by calling
|
|
|
|
|
`RouterModule.forRoot()` _within_ the `imports` array, like this:
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="ngmodule-imports">
|
|
|
|
|
</code-example>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
<div class="l-sub-section">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The method is called `forRoot()` because you configure the router at the application's root level.
|
|
|
|
|
The `forRoot()` method supplies the service providers and directives needed for routing,
|
|
|
|
|
and performs the initial navigation based on the current browser URL.
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
</div>
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
## Add _RouterOutlet_
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Open the `AppComponent` template replace the `<app-heroes>` element with a `<router-outlet>` element.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app.component.html"
|
|
|
|
|
region="outlet"
|
|
|
|
|
title="src/app/app.component.html (router-outlet)">
|
2017-03-31 07:23:16 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You removed `<app-heroes>` because you will only display the `HeroesComponent` when the user navigates to it.
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `<router-outlet>` tells the router where to display routed views.
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
<div class="l-sub-section">
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `RouterOutlet` is one of the router directives that became available to the `AppComponent`
|
|
|
|
|
because `AppModule` imports `AppRoutingModule` which exported `RouterModule`.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
</div>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
#### Try it
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You should still be running with this CLI command.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example language="sh" class="code-shell">
|
|
|
|
|
ng serve
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The browser should refresh and display the app title but not the list of heroes.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Look at the browser's address bar.
|
|
|
|
|
The URL ends in `/`.
|
|
|
|
|
The route path to `HeroesComponent` is `/heroes`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Append `/heroes` to the URL in the browser address bar.
|
|
|
|
|
You should see the familiar heroes master/detail view.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a routerlink}
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2018-02-22 11:08:07 -05:00
|
|
|
|
## Add a navigation link (`routerLink`)
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Users shouldn't have to paste a route URL into the address bar.
|
|
|
|
|
They should be able to click a link to navigate.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add a `<nav>` element and, within that, an anchor element that, when clicked,
|
|
|
|
|
triggers navigation to the `HeroesComponent`.
|
|
|
|
|
The revised `AppComponent` template looks like this:
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/app.component.html"
|
|
|
|
|
region="heroes"
|
|
|
|
|
title="src/app/app.component.html (heroes RouterLink)">
|
|
|
|
|
</code-example>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
A [`routerLink` attribute](#routerlink) is set to `"/heroes"`,
|
|
|
|
|
the string that the router matches to the route to `HeroesComponent`.
|
|
|
|
|
The `routerLink` is the selector for the [`RouterLink` directive](#routerlink)
|
|
|
|
|
that turns user clicks into router navigations.
|
|
|
|
|
It's another of the public directives in the `RouterModule`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The browser refreshes and displays the app title and heroes link,
|
|
|
|
|
but not the heroes list.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Click the link.
|
|
|
|
|
The address bar updates to `/heroes` and the list of heroes appears.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
<div class="l-sub-section">
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Make this and future navigation links look better by adding private CSS styles to `app.component.css`
|
|
|
|
|
as listed in the [final code review](#appcomponent) below.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-04-10 11:51:13 -04:00
|
|
|
|
</div>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
## Add a dashboard view
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Routing makes more sense when there are multiple views.
|
|
|
|
|
So far there's only the heroes view.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add a `DashboardComponent` using the CLI:
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example language="sh" class="code-shell">
|
|
|
|
|
ng generate component dashboard
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The CLI generates the files for the `DashboardComponent` and declares it in `AppModule`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Replace the default file content in these three files as follows and then return for a little discussion:
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-tabs>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.1.html">
|
|
|
|
|
</code-pane>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts">
|
|
|
|
|
</code-pane>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css">
|
|
|
|
|
</code-pane>
|
|
|
|
|
</code-tabs>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The _template_ presents a grid of hero name links.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
* The `*ngFor` repeater creates as many links as are in the component's `heroes` array.
|
|
|
|
|
* The links are styled as colored blocks by the `dashboard.component.css`.
|
|
|
|
|
* The links don't go anywhere yet but [they will shortly](#hero-details).
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The _class_ is similar to the `HeroesComponent` class.
|
|
|
|
|
* It defines a `heroes` array property.
|
|
|
|
|
* The constructor expects Angular to inject the `HeroService` into a private `heroService` property.
|
|
|
|
|
* The `ngOnInit()` lifecycle hook calls `getHeroes`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
This `getHeroes` reduces the number of heroes displayed to four
|
|
|
|
|
(2nd, 3rd, 4th, and 5th).
|
2017-03-30 15:04:18 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/dashboard/dashboard.component.ts" region="getHeroes">
|
2017-03-31 07:23:16 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Add the dashboard route
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
To navigate to the dashboard, the router needs an appropriate route.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Import the `DashboardComponent` in the `AppRoutingModule`.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="import-dashboard"
|
|
|
|
|
title="src/app/app-routing.module.ts (import DashboardComponent)">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add a route to the `AppRoutingModule.routes` array that matches a path to the `DashboardComponent`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="dashboard-route">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Add a default route
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
When the app starts, the browsers address bar points to the web site's root.
|
|
|
|
|
That doesn't match any existing route so the router doesn't navigate anywhere.
|
|
|
|
|
The space below the `<router-outlet>` is blank.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
To make the app navigate to the dashboard automatically, add the following
|
|
|
|
|
route to the `AppRoutingModule.Routes` array.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app-routing.module.ts" region="redirect-route">
|
|
|
|
|
</code-example>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
This route redirects a URL that fully matches the empty path to the route whose path is `'/dashboard'`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-12 13:17:13 -05:00
|
|
|
|
After the browser refreshes, the router loads the `DashboardComponent`
|
2017-11-06 13:02:18 -05:00
|
|
|
|
and the browser address bar shows the `/dashboard` URL.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Add dashboard link to the shell
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The user should be able to navigate back and forth between the
|
|
|
|
|
`DashboardComponent` and the `HeroesComponent` by clicking links in the
|
|
|
|
|
navigation area near the top of the page.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add a dashboard navigation link to the `AppComponent` shell template, just above the *Heroes* link.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/app.component.html" title="src/app/app.component.html">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
After the browser refreshes you can navigate freely between the two views by clicking the links.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a hero-details}
|
|
|
|
|
## Navigating to hero details
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `HeroDetailsComponent` displays details of a selected hero.
|
|
|
|
|
At the moment the `HeroDetailsComponent` is only visible at the bottom of the `HeroesComponent`
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The user should be able to get to these details in three ways.
|
2017-11-27 16:38:30 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
1. By clicking a hero in the dashboard.
|
|
|
|
|
1. By clicking a hero in the heroes list.
|
|
|
|
|
1. By pasting a "deep link" URL into the browser address bar that identifies the hero to display.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
In this section, you'll enable navigation to the `HeroDetailsComponent`
|
|
|
|
|
and liberate it from the `HeroesComponent`.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2018-02-22 11:08:07 -05:00
|
|
|
|
### Delete _hero details_ from `HeroesComponent`
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
When the user clicks a hero item in the `HeroesComponent`,
|
|
|
|
|
the app should navigate to the `HeroDetailComponent`,
|
|
|
|
|
replacing the heroes list view with the hero detail view.
|
|
|
|
|
The heroes list view should no longer show hero details as it does now.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Open the `HeroesComponent` template (`heroes/heroes.component.html`) and
|
|
|
|
|
delete the `<app-hero-detail>` element from the bottom.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Clicking a hero item now does nothing.
|
|
|
|
|
You'll [fix that shortly](#heroes-component-links) after you enable routing to the `HeroDetailComponent`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Add a _hero detail_ route
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
A URL like `~/detail/11` would be a good URL for navigating to the *Hero Detail* view of the hero whose `id` is `11`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Open `AppRoutingModule` and import `HeroDetailComponent`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="import-herodetail"
|
|
|
|
|
title="src/app/app-routing.module.ts (import HeroDetailComponent)">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Then add a _parameterized_ route to the `AppRoutingModule.routes` array that matches the path pattern to the _hero detail_ view.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="detail-route">
|
|
|
|
|
</code-example>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The colon (:) in the `path` indicates that `:id` is a placeholder for a specific hero `id`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
At this point, all application routes are in place.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/app-routing.module.ts"
|
|
|
|
|
region="routes"
|
|
|
|
|
title="src/app/app-routing.module.ts (all routes)">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2018-02-22 11:08:07 -05:00
|
|
|
|
### `DashboardComponent` hero links
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `DashboardComponent` hero links do nothing at the moment.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Now that the router has a route to `HeroDetailComponent`,
|
|
|
|
|
fix the dashboard hero links to navigate via the _parameterized_ dashboard route.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/dashboard/dashboard.component.html"
|
|
|
|
|
region="click"
|
|
|
|
|
title="src/app/dashboard/dashboard.component.html (hero links)">
|
|
|
|
|
</code-example>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You're using Angular [interpolation binding](guide/template-syntax#interpolation) within the `*ngFor` repeater
|
2018-04-23 17:56:21 -04:00
|
|
|
|
to insert the current iteration's `hero.id` into each
|
2017-11-06 13:02:18 -05:00
|
|
|
|
[`routerLink`](#routerlink).
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a heroes-component-links}
|
2018-02-22 11:08:07 -05:00
|
|
|
|
### `HeroesComponent` hero links
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The hero items in the `HeroesComponent` are `<li>` elements whose click events
|
|
|
|
|
are bound to the component's `onSelect()` method.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt4/src/app/heroes/heroes.component.html"
|
|
|
|
|
region="list"
|
|
|
|
|
title="src/app/heroes/heroes.component.html (list with onSelect)">
|
|
|
|
|
</code-example>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Strip the `<li>` back to just its `*ngFor`,
|
|
|
|
|
wrap the badge and name in an anchor element (`<a>`),
|
|
|
|
|
and add a `routerLink` attribute to the anchor that
|
|
|
|
|
is the same as in the dashboard template
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/heroes/heroes.component.html"
|
|
|
|
|
region="list"
|
|
|
|
|
title="src/app/heroes/heroes.component.html (list with links)">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You'll have to fix the private stylesheet (`heroes.component.css`) to make
|
|
|
|
|
the list look as it did before.
|
|
|
|
|
Revised styles are in the [final code review](#heroescomponent) at the bottom of this guide.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
#### Remove dead code (optional)
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
While the `HeroesComponent` class still works,
|
|
|
|
|
the `onSelect()` method and `selectedHero` property are no longer used.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
It's nice to tidy up and you'll be grateful to yourself later.
|
|
|
|
|
Here's the class after pruning away the dead code.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/heroes/heroes.component.ts"
|
|
|
|
|
region="class"
|
|
|
|
|
title="src/app/heroes/heroes.component.ts (cleaned up)" linenums="false">
|
2017-03-27 11:08:53 -04:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
## Routable *HeroDetailComponent*
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Previously, the parent `HeroesComponent` set the `HeroDetailComponent.hero`
|
|
|
|
|
property and the `HeroDetailComponent` displayed the hero.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
`HeroesComponent` doesn't do that anymore.
|
|
|
|
|
Now the router creates the `HeroDetailComponent` in response to a URL such as `~/detail/11`.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `HeroDetailComponent` needs a new way to obtain the _hero-to-display_.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
* Get the route that created it,
|
|
|
|
|
* Extract the `id` from the route
|
|
|
|
|
* Acquire the hero with that `id` from the server via the `HeroService`
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add the following imports:
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/hero-detail/hero-detail.component.ts"
|
|
|
|
|
region="added-imports"
|
|
|
|
|
title="src/app/hero-detail/hero-detail.component.ts">
|
|
|
|
|
</code-example>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a hero-detail-ctor}
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Inject the `ActivatedRoute`, `HeroService`, and `Location` services
|
|
|
|
|
into the constructor, saving their values in private fields:
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ctor">
|
|
|
|
|
</code-example>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The [`ActivatedRoute`](api/router/ActivatedRoute) holds information about the route to this instance of the `HeroDetailComponent`.
|
|
|
|
|
This component is interested in the route's bag of parameters extracted from the URL.
|
|
|
|
|
The _"id"_ parameter is the `id` of the hero to display.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The [`HeroService`](tutorial/toh-pt4) gets hero data from the remote server
|
|
|
|
|
and this component will use it to get the _hero-to-display_.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The [`location`](api/common/Location) is an Angular service for interacting with the browser.
|
|
|
|
|
You'll use it [later](#goback) to navigate back to the view that navigated here.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Extract the _id_ route parameter
|
2017-03-30 15:04:18 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
In the `ngOnInit()` [lifecycle hook](guide/lifecycle-hooks#oninit)
|
|
|
|
|
call `getHero()` and define it as follows.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="ngOnInit">
|
2017-02-22 13:09:39 -05:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `route.snapshot` is a static image of the route information shortly after the component was created.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The `paramMap` is a dictionary of route parameter values extracted from the URL.
|
|
|
|
|
The `"id"` key returns the `id` of the hero to fetch.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Route parameters are always strings.
|
|
|
|
|
The JavaScript (+) operator converts the string to a number,
|
|
|
|
|
which is what a hero `id` should be.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The browser refreshes and the app crashes with a compiler error.
|
|
|
|
|
`HeroService` doesn't have a `getHero()` method.
|
|
|
|
|
Add it now.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2018-02-22 11:08:07 -05:00
|
|
|
|
### Add `HeroService.getHero()`
|
2017-03-30 15:04:18 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Open `HeroService` and add this `getHero()` method
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/hero.service.ts"
|
|
|
|
|
region="getHero"
|
|
|
|
|
title="src/app/hero.service.ts (getHero)">
|
2017-02-22 13:09:39 -05:00
|
|
|
|
</code-example>
|
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<div class="alert is-important">
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Note the backticks ( ` ) that
|
|
|
|
|
define a JavaScript
|
|
|
|
|
[_template literal_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) for embedding the `id`.
|
|
|
|
|
</div>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Like [`getHeroes()`](tutorial/toh-pt4#observable-heroservice),
|
|
|
|
|
`getHero()` has an asynchronous signature.
|
|
|
|
|
It returns a _mock hero_ as an `Observable`, using the RxJS `of()` function.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You'll be able to re-implement `getHero()` as a real `Http` request
|
|
|
|
|
without having to change the `HeroDetailComponent` that calls it.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
#### Try it
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
The browser refreshes and the app is working again.
|
|
|
|
|
You can click a hero in the dashboard or in the heroes list and navigate to that hero's detail view.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
If you paste `localhost:4200/detail/11` in the browser address bar,
|
|
|
|
|
the router navigates to the detail view for the hero with `id: 11`, "Mr. Nice".
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a goback}
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
### Find the way back
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
By clicking the browser's back button,
|
|
|
|
|
you can go back to the hero list or dashboard view,
|
|
|
|
|
depending upon which sent you to the detail view.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
It would be nice to have a button on the `HeroDetail` view that can do that.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add a *go back* button to the bottom of the component template and bind it
|
|
|
|
|
to the component's `goBack()` method.
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example
|
|
|
|
|
path="toh-pt5/src/app/hero-detail/hero-detail.component.html"
|
|
|
|
|
region="back-button"
|
|
|
|
|
title="src/app/hero-detail/hero-detail.component.html (back button)">
|
|
|
|
|
</code-example>
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Add a `goBack()` _method_ to the component class that navigates backward one step
|
|
|
|
|
in the browser's history stack
|
|
|
|
|
using the `Location` service that you [injected previously](#hero-detail-ctor).
|
2017-03-31 07:23:16 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-example path="toh-pt5/src/app/hero-detail/hero-detail.component.ts" region="goBack" title="src/app/hero-detail/hero-detail.component.ts (goBack)">
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
</code-example>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Refresh the browser and start clicking.
|
|
|
|
|
Users can navigate around the app, from the dashboard to hero details and back,
|
|
|
|
|
from heroes list to the mini detail to the hero details and back to the heroes again.
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
You've met all of the navigational requirements that propelled this page.
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
## Final code review
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
Here are the code files discussed on this page and your app should look like this <live-example></live-example>.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a approutingmodule}
|
|
|
|
|
{@a appmodule}
|
2018-02-22 11:08:07 -05:00
|
|
|
|
#### _AppRoutingModule_, _AppModule_, and _HeroService_
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-tabs>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/app-routing.module.ts"
|
|
|
|
|
path="toh-pt5/src/app/app-routing.module.ts">
|
|
|
|
|
</code-pane>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/app.module.ts"
|
|
|
|
|
path="toh-pt5/src/app/app.module.ts">
|
|
|
|
|
</code-pane>
|
2018-02-22 11:08:07 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/hero.service.ts"
|
|
|
|
|
path="toh-pt5/src/app/hero.service.ts">
|
|
|
|
|
</code-pane>
|
2017-11-06 13:02:18 -05:00
|
|
|
|
</code-tabs>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a appcomponent}
|
|
|
|
|
#### _AppComponent_
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-tabs>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/app.component.html"
|
|
|
|
|
path="toh-pt5/src/app/app.component.html">
|
|
|
|
|
</code-pane>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/app.component.css"
|
|
|
|
|
path="toh-pt5/src/app/app.component.css">
|
|
|
|
|
</code-pane>
|
|
|
|
|
</code-tabs>
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a dashboardcomponent}
|
|
|
|
|
#### _DashboardComponent_
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-tabs>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/dashboard/dashboard.component.html" path="toh-pt5/src/app/dashboard/dashboard.component.html">
|
|
|
|
|
</code-pane>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/dashboard/dashboard.component.ts" path="toh-pt5/src/app/dashboard/dashboard.component.ts">
|
|
|
|
|
</code-pane>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/dashboard/dashboard.component.css" path="toh-pt5/src/app/dashboard/dashboard.component.css">
|
|
|
|
|
</code-pane>
|
|
|
|
|
</code-tabs>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a heroescomponent}
|
|
|
|
|
#### _HeroesComponent_
|
2018-02-22 11:08:07 -05:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-tabs>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/heroes/heroes.component.html" path="toh-pt5/src/app/heroes/heroes.component.html">
|
|
|
|
|
</code-pane>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/heroes/heroes.component.ts"
|
|
|
|
|
path="toh-pt5/src/app/heroes/heroes.component.ts">
|
|
|
|
|
</code-pane>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/heroes/heroes.component.css"
|
|
|
|
|
path="toh-pt5/src/app/heroes/heroes.component.css">
|
|
|
|
|
</code-pane>
|
|
|
|
|
</code-tabs>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
{@a herodetailcomponent}
|
|
|
|
|
#### _HeroDetailComponent_
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-tabs>
|
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/hero-detail/hero-detail.component.html" path="toh-pt5/src/app/hero-detail/hero-detail.component.html">
|
|
|
|
|
</code-pane>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/hero-detail/hero-detail.component.ts" path="toh-pt5/src/app/hero-detail/hero-detail.component.ts">
|
|
|
|
|
</code-pane>
|
2017-03-27 11:08:53 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
<code-pane
|
|
|
|
|
title="src/app/hero-detail/hero-detail.component.css" path="toh-pt5/src/app/hero-detail/hero-detail.component.css">
|
|
|
|
|
</code-pane>
|
|
|
|
|
</code-tabs>
|
2017-03-31 19:57:13 -04:00
|
|
|
|
|
2017-11-06 13:02:18 -05:00
|
|
|
|
## Summary
|
2017-02-22 13:09:39 -05:00
|
|
|
|
|
2017-03-31 19:57:13 -04:00
|
|
|
|
* You added the Angular router to navigate among different components.
|
2017-11-13 21:38:03 -05:00
|
|
|
|
* You turned the `AppComponent` into a navigation shell with `<a>` links and a `<router-outlet>`.
|
2017-11-06 13:02:18 -05:00
|
|
|
|
* You configured the router in an `AppRoutingModule`
|
|
|
|
|
* You defined simple routes, a redirect route, and a parameterized route.
|
|
|
|
|
* You used the `routerLink` directive in anchor elements.
|
|
|
|
|
* You refactored a tightly-coupled master/detail view into a routed detail view.
|
|
|
|
|
* You used router link parameters to navigate to the detail view of a user-selected hero.
|
2017-03-31 19:57:13 -04:00
|
|
|
|
* You shared the `HeroService` among multiple components.
|