روتر (Router)
«روتر در انگولار» راهنماییِ مسیرهاست، مثل تابلوی راهنمای مدرسه. «روتر (Router)» آدرس ها را به نماها وصل می کند. سپس با «RouterOutlet» خروجی را نشان می دهد. همچنین با «routerLink» جابه جا می شویم، بدون رفرش کامل. در نهایت، لینک فعال را هایلایت می کنیم.
پایه های روتر در انگولار
رابط کاربر با URL هدایت می شود. «RouterOutlet» جای رندر کامپوننت است. «routerLink» ناوبری بدون رفرش می دهد. برای دموها، از withHashLocation() استفاده کن تا لینک ها بدون تنظیمات سرور کار کنند.
شروع سریع روتر
import { provideRouter, withHashLocation, RouterOutlet, RouterLink } from '@angular/router';
const routes = [
{ path: '', component: Home },
{ path: 'about', component: About }
];
bootstrapApplication(App, {
providers: [provideRouter(routes, withHashLocation())]
});
// Template
// <a routerLink="/about">About</a>
// <router-outlet></router-outlet>
نکته: از routerLink استفاده کن، نه href. چون href صفحه را رفرش می کند.
مثال کامل مسیرهای پایه
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { provideRouter, RouterOutlet, RouterLink, withHashLocation } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink],
template: `
<h3>Router</h3>
<nav>
<a routerLink="/">Home</a> |
<a routerLink="/about">About</a>
</nav>
<router-outlet></router-outlet>
`
})
export class App {}
@Component({
standalone: true,
template: `<p>Home works!</p>`
})
export class Home {}
@Component({
standalone: true,
template: `<p>About works!</p>`
})
export class About {}
const routes = [
{ path: '', component: Home },
{ path: 'about', component: About }
];
bootstrapApplication(App, {
providers: [provideRouter(routes, withHashLocation())]
});
پارامترهای مسیر
برای مسیرهای پویا از :id استفاده کن. سپس با «ActivatedRoute» مقدار پارامتر را بگیر. برای همان مسیر با پارامتر جدید، به paramMap گوش بده.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, OnInit, inject } from '@angular/core';
import { provideRouter, RouterOutlet, RouterLink, RouterLinkActive, ActivatedRoute, withHashLocation } from '@angular/router';
@Component({
selector: 'home-cmp',
standalone: true,
template: `<p>Home works!</p>`
})
export class Home {}
@Component({
selector: 'product-cmp',
standalone: true,
template: `<p>Product ID: {{ id }}</p>`
})
export class Product implements OnInit {
id = '';
private route = inject(ActivatedRoute);
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id') ?? '';
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink, RouterLinkActive],
template: `
<h3>Router Params</h3>
<nav>
<a routerLink="/">Home</a> |
<a routerLink="/product/1" routerLinkActive="active">Product 1</a> |
<a routerLink="/product/2" routerLinkActive="active">Product 2</a>
</nav>
<router-outlet></router-outlet>
`,
styles: [`nav a { margin-right: 6px; } .active { font-weight: bold; }`]
})
export class App {}
const routes = [
{ path: '', component: Home },
{ path: 'product/:id', component: Product }
];
bootstrapApplication(App, {
providers: [provideRouter(routes, withHashLocation())]
});
لینک فعال (routerLinkActive)
برای برجسته سازی لینک جاری از routerLinkActive استفاده کن. برای ریشه، گزینه { exact: true } را بگذار.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { provideRouter, RouterOutlet, RouterLink, RouterLinkActive, withHashLocation } from '@angular/router';
@Component({
standalone: true,
template: `<p>Home works!</p>`
})
export class Home {}
@Component({
standalone: true,
template: `<p>About works!</p>`
})
export class About {}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink, RouterLinkActive],
styles: [`
nav a { margin-right: 8px; text-decoration: none; }
.active { font-weight: 600; color: seagreen; }
`],
template: `
<h3>Active Links (routerLinkActive)</h3>
<nav>
<a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Home</a>
<a routerLink="/about" routerLinkActive="active">About</a>
</nav>
<router-outlet></router-outlet>
`
})
export class App {}
const routes = [
{ path: '', component: Home },
{ path: 'about', component: About }
];
bootstrapApplication(App, {
providers: [provideRouter(routes, withHashLocation())]
});
لود تنبل (Lazy Loading)
کد را هنگام ناوبری بارگذاری کن. با loadComponent یا loadChildren بسته ها را تقسیم کن. این کار زمان شروع را بهتر می کند.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { provideRouter, RouterOutlet, RouterLink, withHashLocation } from '@angular/router';
@Component({
standalone: true,
template: `<p>Home works!</p>`
})
export class Home {}
@Component({
standalone: true,
template: `<p>About works (lazy)!</p>`
})
export class About {}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink],
styles: [`
nav a { margin-right: 8px; text-decoration: none; }
`],
template: `
<h3>Lazy-loaded Component (loadComponent)</h3>
<nav>
<a routerLink="/">Home</a>
<a routerLink="/about">About (lazy)</a>
</nav>
<router-outlet></router-outlet>
`
})
export class App {}
const routes = [
{ path: '', component: Home },
{ path: 'about', loadComponent: () => Promise.resolve(About) }
];
bootstrapApplication(App, {
providers: [provideRouter(routes, withHashLocation())]
});
هشدار: مسیرهای گیرنده همه چیز را آخر بگذار. وگرنه بقیه مسیرها عمل نمی کنند.
گارد مسیر (canActivate)
«گارد (Guard)» اجازه ورود می دهد یا می گیرد. می تواند true، false یا UrlTree بدهد. همچنین می تواند ناهمگام باشد.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component, inject } from '@angular/core';
import { provideRouter, RouterOutlet, RouterLink, withHashLocation, Router } from '@angular/router';
let loggedIn = false;
export const authGuard = () => {
if (loggedIn) {
return true;
}
const router = inject(Router);
return router.createUrlTree(['/']);
};
@Component({
standalone: true,
template: `<p>Home (public).</p>\n<p>Login to access protected route.</p>`
})
export class Home {}
@Component({
standalone: true,
template: `<p>Protected works! You are logged in.</p>`
})
export class Protected {}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink],
styles: [`
nav a { margin-right: 8px; text-decoration: none; }
.status { margin-left: 8px; font-weight: 600; }
`],
template: `
<h3>Route Guard (canActivate)</h3>
<div class="toolbar">
<button (click)="toggle()">{{ loggedIn ? 'Log out' : 'Log in' }}</button>
<span class="status">Status: {{ loggedIn ? 'Logged in' : 'Logged out' }}</span>
</div>
<nav>
<a routerLink="/">Home</a>
<a routerLink="/protected">Protected</a>
</nav>
<router-outlet></router-outlet>
`
})
export class App {
get loggedIn() {
return loggedIn;
}
toggle() {
loggedIn = !loggedIn;
}
}
const routes = [
{ path: '', component: Home },
{ path: 'protected', component: Protected, canActivate: [authGuard] }
];
bootstrapApplication(App, {
providers: [provideRouter(routes, withHashLocation())]
});
نکته: برای فرم ها به فرم ها در انگولار برو. همچنین منطق مشترک را در سرویس ها نگه دار.
گام های عملی سریع
- مسیرها را در آرایه
routesتعریف کن. - با
provideRouter()روتر را فعال کن. - در قالب،
routerLinkوRouterOutletبگذار.
جمع بندی سریع
- روتر در انگولار رابط را با URL هماهنگ می کند.
- لینک ها را با routerLink بساز، نه href.
- پارامترها را با ActivatedRoute بخوان.
- لود تنبل، شروع برنامه را سریع تر می کند.
- گاردها دسترسی مسیرها را کنترل می کنند.