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

Angular路由导航问题:Profile页面无法跳转至Users页面

Angular路由导航问题:Profile页面无法跳转至Users页面

问题描述

我正在学习Angular并开发图书馆管理项目,当前遇到路由导航障碍:管理员登录后,可从/admin/(admin:home)主页跳转至/profile/:email页面和admin/(admin:list-users)页面,但无法从Profile页面直接跳转至Users页面。项目采用命名router outlet实现多角色差异化界面,且Profile路由为通用路由,不可嵌套。

尝试从Profile页面跳转至Users页面时,出现错误:

NG04002: Cannot match any routes. URL Segment: 'profile/abc@gmail.com'

修改侧边栏的routerLink写法后,又导致无法从Admin主页跳转至Users页面,出现错误:

Error: NG04002: Cannot match any routes. URL Segment: 'admin'

相关代码

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginGuardGuard } from './shared/guard/login-guard.guard';
import { SignUpComponent } from './sign-up/sign-up.component';

const routes: Routes = [
  {
    path: '',
    redirectTo: 'login',
    pathMatch: 'full'
  },
  {
    path: 'login',
    loadChildren: () => import('./login/login.module').then(x => x.LoginModule)
  },
  {
    path: 'signup',
    loadChildren: () => import('./sign-up/sign-up.module').then(x => x.SignUpModule)
  },
  {
    path: 'profile/:email', component: SignUpComponent, canActivate: [LoginGuardGuard],
  },
  {
    path: 'book/edit/:id',
    loadChildren: () => import('./book/book.module').then(x => x.BookModule)
  },
  {
    path: 'book/add',
    loadChildren: () => import('./book/book.module').then(x => x.BookModule)
  }

];

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

app.component.html

<nav-bar></nav-bar>

<div class="container-fluid">
  <router-outlet></router-outlet>
</div>

admin-home-page-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginGuardGuard } from 'src/app/shared/guard/login-guard.guard';
import { BookListDisplayComponent } from '../shared/components/book-list-display/book-list-display.component';
import { AdminHomePageComponent } from './components/home-page/admin-home-page.component';
import { UsersListComponent } from './components/users-list/users-list.component';


const routes: Routes = [
  {
    path: 'admin', canActivate: [LoginGuardGuard], component: AdminHomePageComponent,
    children: [
      {
        path: 'home', component: BookListDisplayComponent, outlet: "admin",
      },
      {
        path: 'list-users', component: UsersListComponent, outlet: "admin"
      },
    ]
  }
];

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

admin-home-page.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-home-page',
  templateUrl: './admin-home-page.component.html',
  styleUrls: ['./admin-home-page.component.css']
})
export class AdminHomePageComponent implements OnInit {

  constructor(private router: Router, private activatedRoute: ActivatedRoute) { }

  ngOnInit(): void {
    this.router.navigate([{ outlets: { admin: ['home'] } }], { relativeTo: this.activatedRoute })
  }

}

admin-home-page.component.html

<admin-side-bar></admin-side-bar>
<div class="container-fluid">
    <router-outlet name="admin"></router-outlet>
</div>

admin-side-bar.component.html(版本1)

<!-- version 1 -->

<nav class="sidebar">
    <div class="logo">
        <a [routerLink]="'summary'">
            <img src="../../../../assets/img/logo.png" alt="Logo" />
        </a>
    </div>

    <div class="navigation">
        <ul class="list-unstyled">
            <li [routerLink]="['/profile',userEmail]" routerLinkActive="active">
                <a>Profile</a>
            </li>
            <li [routerLink]="[{ outlets: { 'admin': ['list-users'] } }]" routerLinkActive="active">
                <a>Users</a>
            </li>
            <li [routerLink]="['/admin/list-permissions']" routerLinkActive="active">
                <a>Permissions</a>
            </li>
            <li [routerLink]="['/admin/books-issue-details']" routerLinkActive="active">
                <a>Book Issue Summary</a>
            </li>
        </ul>
    </div>
</nav>

admin-side-bar.component.html(版本2)

<!-- version 2 -->

<nav class="sidebar">
    <div class="logo">
        <a [routerLink]="'summary'">
            <img src="../../../../assets/img/logo.png" alt="Logo" />
        </a>
    </div>

    <div class="navigation">
        <ul class="list-unstyled">
            <li [routerLink]="['/profile',userEmail]" routerLinkActive="active">
                <a>Profile</a>
            </li>
            <li [routerLink]="['profile', userEmail,{ outlets: { 'admin': ['list-users'] } }]"
                routerLinkActive="active">
                <a>Users</a>
            </li>
            <li [routerLink]="['/admin/list-permissions']" routerLinkActive="active">
                <a>Permissions</a>
            </li>
            <li [routerLink]="['/admin/books-issue-details']" routerLinkActive="active">
                <a>Book Issue Summary</a>
            </li>
        </ul>
    </div>
</nav>

解决方案

问题根源

从Profile页面跳转时,当前主路由是/profile/:email,而Users页面的admin命名路由依赖于/admin主路由的上下文。版本1的写法仅指定了命名路由,未切换主路由回/admin;版本2错误地将profile作为主路由前缀,导致路由规则不匹配。

修复步骤

修改侧边栏中Users按钮的routerLink,明确指定主路由切换到/admin,同时激活admin命名路由的list-users:

<li [routerLink]="['/admin', { outlets: { 'admin': ['list-users'] } }]" routerLinkActive="active">
    <a>Users</a>
</li>

原理说明

  • ['/admin', { outlets: { 'admin': ['list-users'] } }] 的作用:
    1. 将主路由切换回/admin,确保处于Admin页面的上下文
    2. 在admin命名路由中加载list-users组件
  • 这种写法无论当前处于/profile/:email还是Admin内部路由,都能正确匹配路由规则,解决双向跳转问题。

额外检查

如果Permissions和Book Issue Summary也是放在admin命名outlet中的组件,需要同步修改它们的路由写法,确保路由一致性;如果它们是独立的Admin子路由,则保持现有写法即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:05:33