You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中navigate未定义错误排查及子路由实现求助

Fixing 'Cannot read property 'navigate' of undefined' & Implementing Nested Outlet Navigation

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 private to the constructor parameter router: Router – this tells Angular to inject the Router instance and automatically assign it to the class property this.router. This is the standard Angular dependency injection pattern.
  • Alternatively, you could keep the class-level router: Router declaration 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 routes array defining the nested outlet structure:
    • UserManagementComponent is the parent, with a child route for the newuser outlet (hosting NewUserComponent)
    • NewUserComponent contains child routes for the newuserinput and newuserorginfo outlets
  • Uncommented and added all required components to the declarations array (you had some commented out earlier)

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 NewUserComponent template includes the required outlets:
    <router-outlet name="newuserinput"></router-outlet>
    <router-outlet name="newuserorginfo"></router-outlet>
    
  • Verify that the parent layout/usermanagement route in your root routing module correctly loads the UserManagementModule.

内容的提问来源于stack exchange,提问作者imnickvaughn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:57:44