docs(toh-5): add AppRoutingModule (#2584)
This commit is contained in:
parent
6f804c6534
commit
2e17d587de
|
@ -0,0 +1,20 @@
|
|||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
import { HeroesComponent } from './heroes.component';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
||||
{ path: 'dashboard', component: DashboardComponent },
|
||||
{ path: 'detail/:id', component: HeroDetailComponent },
|
||||
{ path: 'heroes', component: HeroesComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class AppRoutingModule {}
|
|
@ -1,9 +1,7 @@
|
|||
// #docplaster
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
|
@ -11,44 +9,27 @@ import { HeroDetailComponent } from './hero-detail.component';
|
|||
import { HeroesComponent } from './heroes.component';
|
||||
import { HeroService } from './hero.service';
|
||||
|
||||
// #docregion routing-module
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
RouterModule.forRoot([
|
||||
{
|
||||
path: '',
|
||||
redirectTo: '/dashboard',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: DashboardComponent
|
||||
},
|
||||
{
|
||||
path: 'detail/:id',
|
||||
component: HeroDetailComponent
|
||||
},
|
||||
{
|
||||
path: 'heroes',
|
||||
component: HeroesComponent
|
||||
}
|
||||
])
|
||||
AppRoutingModule
|
||||
],
|
||||
// #enddocregion routing
|
||||
// #docregion dashboard, hero-detail
|
||||
// #enddocregion routing-module
|
||||
// #docregion dashboard
|
||||
declarations: [
|
||||
AppComponent,
|
||||
DashboardComponent,
|
||||
HeroDetailComponent,
|
||||
HeroesComponent
|
||||
],
|
||||
// #enddocregion dashboard, hero-detail
|
||||
providers: [
|
||||
HeroService
|
||||
],
|
||||
// #enddocregion dashboard
|
||||
providers: [ HeroService ],
|
||||
bootstrap: [ AppComponent ]
|
||||
// #docregion routing
|
||||
// #docregion routing-module
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
export class AppModule { }
|
||||
// #enddocregion routing-module
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
import { HeroesComponent } from './heroes.component';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
||||
{ path: 'dashboard', component: DashboardComponent },
|
||||
{ path: 'detail/:id', component: HeroDetailComponent },
|
||||
{ path: 'heroes', component: HeroesComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class AppRoutingModule {}
|
|
@ -9,11 +9,12 @@ import { NgModule } from '@angular/core';
|
|||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { HttpModule } from '@angular/http';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
// #enddocregion v1
|
||||
// Imports for loading & configuring the in-memory web api
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
|
||||
import { InMemoryWebApiModule } from 'angular-in-memory-web-api/in-memory-web-api.module';
|
||||
import { InMemoryDataService } from './in-memory-data.service';
|
||||
|
||||
// #docregion v1
|
||||
|
@ -36,25 +37,7 @@ import { HeroSearchComponent } from './hero-search.component';
|
|||
InMemoryWebApiModule.forRoot(InMemoryDataService),
|
||||
// #enddocregion in-mem-web-api
|
||||
// #docregion v1
|
||||
RouterModule.forRoot([
|
||||
{
|
||||
path: '',
|
||||
redirectTo: '/dashboard',
|
||||
pathMatch: 'full'
|
||||
},
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: DashboardComponent
|
||||
},
|
||||
{
|
||||
path: 'detail/:id',
|
||||
component: HeroDetailComponent
|
||||
},
|
||||
{
|
||||
path: 'heroes',
|
||||
component: HeroesComponent
|
||||
}
|
||||
])
|
||||
AppRoutingModule
|
||||
],
|
||||
// #docregion search
|
||||
declarations: [
|
||||
|
@ -67,10 +50,7 @@ import { HeroSearchComponent } from './hero-search.component';
|
|||
// #docregion v1, v2
|
||||
],
|
||||
// #enddocregion search
|
||||
providers: [
|
||||
HeroService,
|
||||
],
|
||||
providers: [ HeroService ],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
export class AppModule { }
|
||||
|
|
|
@ -644,17 +644,67 @@ block extract-id
|
|||
Refresh the browser and select a hero from the dashboard; the app should navigate directly to that hero’s details.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Refactor routes to a _Routing Module_
|
||||
|
||||
Almost 20 lines of `AppModule` are devoted to configuring four routes.
|
||||
Most application have many more routes and they [add guard services](../guide/router.html#guards)
|
||||
to protect against unwanted or unauthorized navigations.
|
||||
Routing considerations could quickly dominate this module and obscure its primary purpose which is to
|
||||
establish key facts about the entire app for the Angular compiler.
|
||||
|
||||
We should refactor the routing configuration into its own class.
|
||||
What kind of class?
|
||||
The current `RouterModule.forRoot()` produces an Angular `ModuleWithProviders` which suggests that a
|
||||
class dedicated to routing should be some kind of module.
|
||||
It should be a [_Routing Module_](../guide/router.htm#routing-module).
|
||||
|
||||
By convention the name of a _Routing Module_ contains the word "Routing" and
|
||||
aligns with the name of the module that declares the components navigated to".
|
||||
|
||||
Create an `app-routing.module.ts` file as a sibling to `app.module.ts`. Give it the following contents extracted from the `AppModule` class:
|
||||
|
||||
+makeExample('app/app-routing.module.ts')
|
||||
:marked
|
||||
Noteworthy points, typical of _Routing Modules_:
|
||||
* Pull the routes into a variable. You might export it in future and it clarifies the _Routing Module_ pattern.
|
||||
|
||||
* Add `RouterModule.forRoot(routes)` to `imports`.
|
||||
|
||||
* Add `RouterModule` to `exports` so that the components in the companion module have access to Router declarables
|
||||
such as `RouterLink` and `RouterOutlet`.
|
||||
|
||||
* No `declarations`! Declarations are the responsibility of the companion module.
|
||||
|
||||
* Add module `providers` for guard services if you have them; there are none in this example.
|
||||
|
||||
### Update _AppModule_
|
||||
|
||||
Now delete the routing configuration from `AppModule` and import the `AppRoutingModule`
|
||||
(_both_ with an ES `import` statement _and_ by adding it to the `NgModule.imports` list).
|
||||
|
||||
Here is the revised `AppModule`, compared to its pre-refactor state:
|
||||
+makeTabs(
|
||||
`toh-5/ts/app/app.module.ts, toh-5/ts/app/app.module.3.ts`,
|
||||
null,
|
||||
`app/app.module.ts (after), app/app.module.ts (before)`)
|
||||
:marked
|
||||
It's simpler and focused on indentifying the key pieces of the application.
|
||||
.l-main-section
|
||||
:marked
|
||||
## Select a Hero in the *HeroesComponent*
|
||||
|
||||
Earlier we added the ability to select a hero from the dashboard.
|
||||
We'll do something similar in the `HeroesComponent`.
|
||||
|
||||
That component's current template exhibits a "master/detail" style with the list of heroes
|
||||
The `HeroesComponent` template exhibits a "master/detail" style with the list of heroes
|
||||
at the top and details of the selected hero below.
|
||||
|
||||
+makeExample('toh-4/ts/app/app.component.ts','template', 'app/heroes.component.ts (current template)')(format=".")
|
||||
|
||||
:marked
|
||||
Our goal is to move the detail to its own view and navigate to it when the user decides to edit a selected hero.
|
||||
|
||||
Delete the `<h1>` at the top (forgot about it during the `AppComponent`-to-`HeroesComponent` conversion).
|
||||
|
||||
Delete the last line of the template with the `<my-hero-detail>` tags.
|
||||
|
@ -663,8 +713,9 @@ block extract-id
|
|||
We're going to display the hero detail on its own page and route to it as we did in the dashboard.
|
||||
|
||||
But we'll throw in a small twist for variety.
|
||||
When the user selects a hero from the list, we *won't* go to the detail page.
|
||||
We'll show a *mini-detail* on *this* page instead and make the user click a button to navigate to the *full detail *page.
|
||||
We are keeping the "master/detail" style but shrinking the detail to a "mini", read-only version.
|
||||
When the user selects a hero from the list, we *don't* go to the detail page.
|
||||
We show a *mini-detail* on *this* page instead and make the user click a button to navigate to the *full detail *page.
|
||||
|
||||
### Add the *mini-detail*
|
||||
|
||||
|
@ -859,6 +910,7 @@ block file-tree-end
|
|||
.file app.component.css
|
||||
.file app.component.ts
|
||||
.file app.module.ts
|
||||
.file app-routing.module.ts
|
||||
.file dashboard.component.css
|
||||
.file dashboard.component.html
|
||||
.file dashboard.component.ts
|
||||
|
@ -895,6 +947,7 @@ block file-tree-end
|
|||
- We shared the `HeroService` among multiple components.
|
||||
- We moved HTML and CSS out of the component file and into their own files.
|
||||
- We added the `uppercase` pipe to format data.
|
||||
- We refactored routes into a `Routing Module` that we import.
|
||||
|
||||
### The Road Ahead
|
||||
|
||||
|
|
|
@ -584,7 +584,7 @@ block filetree
|
|||
- We configured an in-memory web API.
|
||||
- We learned how to use !{_Observable}s.
|
||||
|
||||
Here are the files we added or changed in this chapter.
|
||||
Here are the files we _added or changed_ in this chapter.
|
||||
|
||||
block file-summary
|
||||
+makeTabs(
|
||||
|
|
Loading…
Reference in New Issue