Building  Large-Scale Web Applications with Angular
上QQ阅读APP看书,第一时间看更新

Adding the child routing component

In the workout-builder directory, add a new TypeScript file named workout-builder.routing.module.ts with the following imports:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { WorkoutBuilderComponent } from './workout-builder.component';
import { WorkoutsComponent } from './workouts/workouts.component';
import { WorkoutComponent } from './workout/workout.component';
import { ExercisesComponent } from './exercises/exercises.component';
import { ExerciseComponent } from './exercise/exercise.component';

As you can see, we are importing the components we just mentioned; they will be part of our Workout Builder (exercise, exercises, workout, and workouts). Along with those imports, we are also importing NgModule from the Angular core module and Routes and RouterModule from the Angular router module. These imports will give us the ability to add and export child routes.

We are not using the Angular CLI here because it does not have a standalone blueprint for creating a routing module. However, you can have the CLI create a routing module at the time that you create a module using the --routing option. In this case, we already had an existing module created so we couldn't use that flag. See https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/routing.md for more details about how to do this.

Then, add the following route configuration to the file:

const routes: Routes = [
{
path: 'builder',
component: WorkoutBuilderComponent,
children: [
{path: '', pathMatch: 'full', redirectTo: 'workouts'},
{path: 'workouts', component: WorkoutsComponent },
{path: 'workout/new', component: WorkoutComponent },
{path: 'workout/:id', component: WorkoutComponent },
{path: 'exercises', component: ExercisesComponent},
{path: 'exercise/new', component: ExerciseComponent },
{path: 'exercise/:id', component: ExerciseComponent }
]
},
];

The first configuration, path: 'builder', sets the base URL for the child routes so that each of the child routes prepends it. The next configuration identifies the WorkoutBuilder component as the feature area root component for the child components in this file. This means it will be the component in which each of the child components is displayed using router-outlet. The final configuration is a list of one or more children that defines the routing for the child components.

One thing to note here is that we have set up Workouts as the default for the child routes with the following configuration:

{path:'', pathMatch: 'full', redirectTo: 'workouts'}, 
 

This configuration indicates that if someone navigates to builder, they will be redirected to the builder/workouts route. The pathMatch: 'full' setting means that the match will only be made if the path after workout/builder is an empty string. This prevents the redirection from happening if the routes are something else, such as workout/builder/exercises or any of the other routes we have configured within this file.

Finally, add the following class declaration preceded by an @NgModule decorator that defines imports and exports for our module:

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class WorkoutBuilderRoutingModule { }

This import is very similar to the one in app.routing-module.ts, with one difference - instead of RouterModule.forRoot, we are using RouterModule.forChild. The reason for the difference may seem self-explanatory: we are creating child routes, not the routes in the root of the application, and this is how we signify that. Under the hood, however, there is a significant difference. This is because we cannot have more than one router service active in our application. forRoot creates the router service but forChild does not.