angular-routing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAngular Routing - Quick Reference
Angular 路由 - 速查指南
Deep Knowledge: Usewith technology:mcp__documentation__fetch_docs, topic:angularfor comprehensive documentation.routing
深度资料:如需完整文档,请使用,指定技术:mcp__documentation__fetch_docs,主题:angularrouting
Route Configuration (Standalone)
独立式路由配置
typescript
// app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{
path: 'dashboard',
loadComponent: () => import('./features/dashboard/dashboard.component')
.then(m => m.DashboardComponent),
},
{
path: 'users',
loadChildren: () => import('./features/users/users.routes')
.then(m => m.USERS_ROUTES),
canActivate: [authGuard],
},
{ path: '**', loadComponent: () => import('./not-found.component').then(m => m.NotFoundComponent) },
];typescript
// app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{
path: 'dashboard',
loadComponent: () => import('./features/dashboard/dashboard.component')
.then(m => m.DashboardComponent),
},
{
path: 'users',
loadChildren: () => import('./features/users/users.routes')
.then(m => m.USERS_ROUTES),
canActivate: [authGuard],
},
{ path: '**', loadComponent: () => import('./not-found.component').then(m => m.NotFoundComponent) },
];Lazy Loading Feature Routes
特性路由懒加载
typescript
// features/users/users.routes.ts
import { Routes } from '@angular/router';
export const USERS_ROUTES: Routes = [
{
path: '',
loadComponent: () => import('./user-list.component').then(m => m.UserListComponent),
},
{
path: ':id',
loadComponent: () => import('./user-detail.component').then(m => m.UserDetailComponent),
resolve: { user: userResolver },
},
];typescript
// features/users/users.routes.ts
import { Routes } from '@angular/router';
export const USERS_ROUTES: Routes = [
{
path: '',
loadComponent: () => import('./user-list.component').then(m => m.UserListComponent),
},
{
path: ':id',
loadComponent: () => import('./user-detail.component').then(m => m.UserDetailComponent),
resolve: { user: userResolver },
},
];Functional Guards (Angular 15+)
函数式守卫(Angular 15+)
typescript
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
return router.createUrlTree(['/login']);
};
export const roleGuard: CanActivateFn = (route) => {
const authService = inject(AuthService);
const requiredRole = route.data['role'] as string;
return authService.hasRole(requiredRole);
};typescript
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
return router.createUrlTree(['/login']);
};
export const roleGuard: CanActivateFn = (route) => {
const authService = inject(AuthService);
const requiredRole = route.data['role'] as string;
return authService.hasRole(requiredRole);
};Functional Resolvers
函数式解析器
typescript
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { UserService } from './user.service';
import { User } from './user.model';
export const userResolver: ResolveFn<User> = (route) => {
const userService = inject(UserService);
const id = Number(route.paramMap.get('id'));
return userService.getById(id);
};typescript
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { UserService } from './user.service';
import { User } from './user.model';
export const userResolver: ResolveFn<User> = (route) => {
const userService = inject(UserService);
const id = Number(route.paramMap.get('id'));
return userService.getById(id);
};Route Parameters with Input Binding
路由参数与输入绑定
typescript
// Enable in app.config.ts: provideRouter(routes, withComponentInputBinding())
@Component({ standalone: true, template: `<p>User {{ id }}</p>` })
export class UserDetailComponent {
@Input() id!: string; // Automatically bound from :id route param
}typescript
// 在app.config.ts中启用:provideRouter(routes, withComponentInputBinding())
@Component({ standalone: true, template: `<p>用户 {{ id }}</p>` })
export class UserDetailComponent {
@Input() id!: string; // 自动绑定自:id路由参数
}Navigation
导航
typescript
import { Router, RouterLink } from '@angular/router';
// Template
// <a [routerLink]="['/users', user.id]">View User</a>
// <a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
// Programmatic
@Component({ ... })
export class SomeComponent {
private router = inject(Router);
navigate() {
this.router.navigate(['/users', 42], {
queryParams: { tab: 'profile' },
});
}
}typescript
import { Router, RouterLink } from '@angular/router';
// 模板
// <a [routerLink]="['/users', user.id]">查看用户</a>
// <a routerLink="/dashboard" routerLinkActive="active">仪表盘</a>
// 编程式导航
@Component({ ... })
export class SomeComponent {
private router = inject(Router);
navigate() {
this.router.navigate(['/users', 42], {
queryParams: { tab: 'profile' },
});
}
}Anti-Patterns
反模式
| Anti-Pattern | Why It's Bad | Correct Approach |
|---|---|---|
| Eager loading all routes | Large bundle size | Use |
| Class-based guards | Verbose, deprecated pattern | Use functional guards with |
| Subscribing to params manually | Boilerplate, leak risk | Use |
| Nested route configs in app.routes | Hard to maintain | Split into feature route files |
| 反模式 | 问题原因 | 正确做法 |
|---|---|---|
| 预加载所有路由 | 包体积过大 | 使用 |
| 基于类的守卫 | 代码冗余,已被弃用 | 使用带 |
| 手动订阅路由参数 | 样板代码多,存在内存泄漏风险 | 使用 |
| 在app.routes中嵌套路由配置 | 难以维护 | 拆分到特性路由文件中 |
Quick Troubleshooting
快速故障排除
| Issue | Likely Cause | Solution |
|---|---|---|
| Route not matching | Order matters | Put specific routes before wildcards |
| Guard not triggering | Not in route config | Add to |
| Lazy load fails | Wrong export | Ensure component is exported |
| Query params lost | Navigate without preserve | Use |
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 路由不匹配 | 路由顺序问题 | 把具体路由放在通配符路由之前 |
| 守卫未触发 | 未添加到路由配置 | 添加到 |
| 懒加载失败 | 导出错误 | 确保组件已正确导出 |
| 查询参数丢失 | 导航时未保留参数 | 使用 |