Angular中navigate未定义错误排查及子路由实现求助
Let's tackle your issues one by one, starting with the immediate router undefined error, then moving on to your navigation requirements.
1. Resolve the "Cannot read property 'navigate' of undefined" Error
The root cause here is that your class-level router property isn't being properly initialized with the injected Router instance. In your constructor, you've declared the router parameter but haven't assigned it to your class property (or used an access modifier to let Angular handle it automatically).
Updated new-user-input.component.ts
import { Component, OnInit } from '@angular/core'; import { slideToRight } from '../../../../router.animations'; import { Router, ActivatedRoute, UrlSegment } from '@angular/router'; @Component({ selector: 'app-new-user-input', templateUrl: './new-user-input.component.html', styleUrls: ['./new-user-input.component.css'], animations: [slideToRight()] }) export class NewUserInputComponent implements OnInit { // Use private/public access modifier to inject and assign the Router automatically constructor(private router: Router, private r: ActivatedRoute) { r.url.subscribe((s: UrlSegment[]) => { console.log("url", s); }); } ngOnInit() { } displaySibling() { console.log(this.router); // This will now be defined // Navigate to the sibling nested outlet this.router.navigate(['../newuserorginfo'], { relativeTo: this.r, outlets: { newuserorginfo: ['newuserorginfo'] } }); } closeBlade() { // Clear the current outlet to return to the parent route this.router.navigate([{ outlets: { newuserinput: null } }], { relativeTo: this.r.parent }); } }
Key Fixes:
- Added
privateto the constructor parameterrouter: Router– this tells Angular to inject the Router instance and automatically assign it to the class propertythis.router. This is the standard Angular dependency injection pattern. - Alternatively, you could keep the class-level
router: Routerdeclaration and manually assign it in the constructor:this.router = router;, but using access modifiers is cleaner.
2. Implement Your Navigation Requirements
First, we need to fix your routing configuration to support nested outlets. Let's update your user-management.module.ts to include the necessary route definitions.
Updated user-management.module.ts
import { HttpModule, JsonpModule } from '@angular/http'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Type, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { CommonModule } from '@angular/common'; import { GridAllModule } from '@syncfusion/ej2-ng-grids'; import { HttpClientModule } from '@angular/common/http'; import { GridModule, ToolbarService, EditService, SortService, GroupService, FilterService, PageService, ContextMenuItem, PdfExportService, ExcelExportService, ContextMenuService, ResizeService, DataSourceChangedEventArgs, DataStateChangeEventArgs } from '@syncfusion/ej2-ng-grids'; import { UserManagementComponent } from './user-management.component'; import { PageHeaderModule } from './../../shared/page-header/page-header.module'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { RouterModule, Routes } from '@angular/router'; import { NewUserOrgInfoComponent } from './new-user/new-user-org-info/new-user-org-info.component'; import { NewUserSupervisorInfoComponent } from './new-user/new-user-supervisor-info/new-user-supervisor-info.component'; import { NewUserSecurityInfoComponent } from './new-user/new-user-security-info/new-user-security-info.component'; import { NewUserInputComponent } from './new-user/new-user-input/new-user-input.component'; // Uncomment and import import { NewUserComponent } from './new-user/new-user.component'; // Import parent component // Define nested route structure for outlets const routes: Routes = [ { path: '', component: UserManagementComponent, children: [ { path: 'newuser', component: NewUserComponent, outlet: 'newuser', children: [ { path: 'newuserinput', component: NewUserInputComponent, outlet: 'newuserinput' }, { path: 'newuserorginfo', component: NewUserOrgInfoComponent, outlet: 'newuserorginfo' } ] } ] } ]; @NgModule({ imports: [ CommonModule, PageHeaderModule, GridModule, RouterModule.forChild(routes), // Add route configuration here NgbModule ], declarations: [ UserManagementComponent, NewUserOrgInfoComponent, NewUserSupervisorInfoComponent, NewUserSecurityInfoComponent, NewUserInputComponent, // Declare the component NewUserComponent // Declare parent component ], providers: [EditService, ToolbarService, SortService, GroupService, FilterService, PageService, ContextMenuService, ResizeService, PdfExportService, ExcelExportService] }) export class UserManagementModule { }
Key Route Setup Notes:
- Added a
routesarray defining the nested outlet structure:UserManagementComponentis the parent, with a child route for thenewuseroutlet (hostingNewUserComponent)NewUserComponentcontains child routes for thenewuserinputandnewuserorginfooutlets
- Uncommented and added all required components to the
declarationsarray (you had some commented out earlier)
Navigation Function Details
1. Navigate from newuserinput to newuserorginfo
The updated displaySibling() method uses relativeTo: this.r to base navigation on the current activated route, ensuring we target the correct nested outlet:
displaySibling() { this.router.navigate(['../newuserorginfo'], { relativeTo: this.r, outlets: { newuserorginfo: ['newuserorginfo'] } }); }
This will take you from https://localhost:4200/layout/usermanagement/(newuser:newuser/(newuserinput:newuserinput)) to https://localhost:4200/layout/usermanagement/(newuser:newuser/(newuserorginfo:newuserorginfo)) as required.
2. Close Current Route & Return to newuser Main Route
The updated closeBlade() method uses relativeTo: this.r.parent to target the parent route of newuserinput, and sets the newuserinput outlet to null to clear it:
closeBlade() { this.router.navigate([{ outlets: { newuserinput: null } }], { relativeTo: this.r.parent }); }
This will navigate you back to https://localhost:4200/layout/usermanagement/(newuser:newuser) when the close button is clicked.
Final Check
- Ensure your
NewUserComponenttemplate includes the required outlets:<router-outlet name="newuserinput"></router-outlet> <router-outlet name="newuserorginfo"></router-outlet> - Verify that the parent
layout/usermanagementroute in your root routing module correctly loads theUserManagementModule.
内容的提问来源于stack exchange,提问作者imnickvaughn

