במאמר הקודם למדנו על הזרקת תלויות Dependency Injection, כעת נלמד על Routing.
באפליקציות מודרניות, ניהול ניווט וראוטינג הוא אחד המרכיבים הקריטיים ביותר. Angular מספקת מערכת ראוטינג עוצמתית המאפשרת ניהול קל ונוח של מסלולים באפליקציה. במאמר זה, נסקור את היסודות של ראוטינג באנגולר, נבין כיצד להגדיר מסלולים ולנהל ניווט בין קומפוננטות שונות.
הגדרת ראוטינג באנגולר
כדי להתחיל להשתמש בראוטינג באנגולר, יש להגדיר מודול ראוטינג באפליקציה. ראשית, נייבא את המודולים הדרושים ונתחיל בהגדרות בסיסיות.
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
בקוד זה, אנו מגדירים שני מסלולים בסיסיים: מסלול ריק המוביל ל-HomeComponent ומסלול נוסף המוביל ל-AboutComponent. לאחר מכן, אנו מייבאים את RouterModule ומשתמשים בפונקציה forRoot() כדי להגדיר את המסלולים.
הוספת ראוטרים לתבנית
כדי להפעיל את הראוטינג באפליקציה, נצטרך להוסיף את הראוטרים לתבנית הראשית של האפליקציה.
<!-- app.component.html -->
<nav>
<a routerLink="/" routerLinkActive="active">Home</a>
<a routerLink="/about" routerLinkActive="active">About</a>
</nav>
<router-outlet></router-outlet>
כאן, אנו מוסיפים קישורים באמצעות routerLink לניווט בין הדפים. כמו כן, אנו מוסיפים את הרכיב <router-outlet> שתפקידו להציג את הקומפוננטות המתאימות בהתאם למסלול הנוכחי.
הגדרת מסלולים דינמיים
אחת מהיכולות המתקדמות של Angular היא היכולת להגדיר מסלולים דינמיים ולקבל פרמטרים מהמסלול. לדוגמה, ניתן להגדיר מסלול שמקבל מזהה של משתמש.
const routes: Routes = [
{ path: 'user/:id', component: UserComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
כדי לקבל את הפרמטר בתוך הקומפוננטה, נשתמש ב-ActivatedRoute:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
userId: string;
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.route.params.subscribe(params => {
this.userId = params['id'];
});
}
}
בקוד זה, אנו מקבלים את פרמטר ה-id מהמסלול ושומרים אותו במשתנה userId בתוך הקומפוננטה.
מסלולים מקוננים
אפליקציות מורכבות דורשות לעיתים קרובות מסלולים מקוננים. אנגולר מאפשרת הגדרה קלה של מסלולים מקוננים באמצעות children.
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: '', component: OverviewComponent },
{ path: 'stats', component: StatsComponent }
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
כאן, אנו מגדירים מסלול ראשי ל-DashboardComponent ומסלולים נוספים מקוננים תחתיו ל-OverviewComponent ו-StatsComponent.
Guard למניעת גישה למסלולים
במקרים מסוימים, נרצה למנוע גישה למסלולים מסוימים למשתמשים שאינם מורשים. נשתמש ב-Guards לשם כך.
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree {
// Add your authentication logic here
return true;
}
}
לאחר יצירת ה-Guard, נוסיף אותו למסלול הרצוי:
const routes: Routes = [
{ path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
כאן, אנו מגדירים שהגישה למסלול admin מוגנת באמצעות ה-AuthGuard שיצרנו.
הטענת מודולים באופן דינמי (Lazy Loading)
בפרויקטים גדולים, הטענת כל הקומפוננטות והמודולים בזמן טעינת הדף הראשונית יכולה להאט את ביצועי האפליקציה. Angular מאפשרת הטענת מודולים באופן דינמי (Lazy Loading) כדי לשפר את הביצועים.
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
במקרה זה, המודול admin נטען רק כאשר המשתמש ניגש למסלול admin, מה שמשפר את זמן הטעינה הראשוני של האפליקציה.
הוספת אנימציות לניווט
כדי לשפר את חוויית המשתמש, ניתן להוסיף אנימציות למעברי ניווט באפליקציה. Angular מספקת תמיכה מובנית להוספת אנימציות באמצעות Angular Animations.
import { trigger, transition, style, animate } from '@angular/animations';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('routeAnimations', [
transition('* <=> *', [
style({ opacity: 0 }),
animate('300ms', style({ opacity: 1 }))
])
])
]
})
export class AppComponent { }
לאחר מכן, נוסיף את האנימציה לתבנית:
<!-- app.component.html -->
<div [@routeAnimations]="o.isActivated ? o.activatedRoute : ''">
<router-outlet #o="outlet"></router-outlet>
</div>
כעת, כל מעבר בין מסלולים ילווה באנימציה של מעבר חלק.
סיכום
במאמר זה, סקרנו את יסודות הראוטינג באנגולר, כולל הגדרת מסלולים בסיסיים, מסלולים דינמיים ומסלולים מקוננים. כמו כן, דיברנו על השימוש ב-Guards, הטענת מודולים באופן דינמי והוספת אנימציות לניווט. ניהול נכון של ראוטינג באפליקציה הוא מרכיב חשוב לחוויית משתמש מוצלחת ולביצועים מיטביים.
אם אתם מעוניינים ללמוד בצורה מעמיקה יותר אתם מוזמנים להתייעץ איתנו על קורס אנגולר.
במאמר הבא נלמד על Pipes באפליקציית Angular.