021-88881776

آموزش مسیریابی و ناوبری (Routing) در Angula

در این آموزش Angular، قصد داریم به بررسی مفاهیم مسیریابی و ناوبری (Routing) در Angular بپردازیم. مسیریابی و ناوبری (Routing) در Angular یکی از مفاهیم اساسی و ضروری است که به شما امکان می‌دهد تا صفحات مختلف وب‌اپلیکیشن خود را مدیریت کنید و به راحتی بین آن‌ها حرکت کنید. این مقاله به‌طور جامع و کامل، مسیریابی و ناوبری (Routing) در Angular را از سطح مبتدی تا پیشرفته پوشش می‌دهد. در این مقاله، با استفاده از مثال‌های عملی و توضیحات ساده، به شما نحوه استفاده از این قابلیت در Angular را یاد خواهیم داد.

مفهوم Routing در Angular

مسیریابی و ناوبری (Routing) در Angular یکی از اصول اصلی برای ساخت وب‌اپلیکیشن‌های پیچیده و چندصفحه‌ای است. مسیریابی (Routing) به شما این امکان را می‌دهد که بین بخش‌های مختلف یک اپلیکیشن جابجا شوید، بدون اینکه نیاز به بارگذاری مجدد صفحه باشد. این قابلیت به اپلیکیشن‌ها امکان می‌دهد تا تجربه کاربری سریع‌تر و روان‌تری ارائه دهند.

چطور مسیریابی در Angular کار می‌کند؟

در Angular، مسیریابی با استفاده از Angular Router انجام می‌شود. Angular Router ابزاری است که در پس‌زمینه تمامی کارهای مرتبط با مسیریابی را انجام می‌دهد. این ابزار مسئول هدایت کاربران به مسیرهای مختلف اپلیکیشن، مدیریت تاریخچه مرورگر (مانند رفتن به عقب یا جلو)، بارگذاری بخش‌های مختلف اپلیکیشن و تعامل با URLها است.

چگونه مسیرها در Angular تعریف می‌شوند؟

در Angular، مسیرها معمولاً به‌وسیله یک شیء به نام Routes تعریف می‌شوند که یک آرایه از مسیرها را شامل می‌شود. هر مسیر با استفاده از یک path مشخص می‌شود که URL آن را نشان می‌دهد، و به یک کامپوننت خاص ارجاع داده می‌شود که باید نمایش داده شود.

مثال ساده:

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent }
];

در این مثال:

وقتی کاربر به URL ‘/’ مراجعه می‌کند، کامپوننت HomeComponent بارگذاری می‌شود.
وقتی کاربر به URL ‘/about’ مراجعه می‌کند، کامپوننت AboutComponent نمایش داده می‌شود.

استفاده از RouterModule برای فعال‌سازی مسیریابی

برای فعال کردن مسیریابی در اپلیکیشن Angular خود، شما باید RouterModule را در ماژول اصلی اپلیکیشن (معمولاً app.module.ts) وارد کنید. در این مرحله، مسیرهای تعریف‌شده را به RouterModule.forRoot() می‌دهید تا Angular بتواند از آن‌ها استفاده کند.

مثال:

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 AppModule {}

 

در این کد، RouterModule.forRoot(routes) مسیرهای شما را به سیستم مسیریابی Angular معرفی می‌کند. هر زمان که کاربر به یکی از این مسیرها دسترسی پیدا کند، Angular Router کامپوننت مربوطه را بارگذاری خواهد کرد.

عملکرد لینک‌ها و ناوبری

برای هدایت کاربران به مسیرهای مختلف، Angular از دستور routerLink استفاده می‌کند. این دستور را می‌توان در هر جزء از اپلیکیشن برای ایجاد لینک‌های مسیریابی استفاده کرد.

مثال:

<a routerLink="/about">About</a>

زمانی که کاربر روی این لینک کلیک کند، Angular Router مسیر ‘/about’ را بارگذاری کرده و کامپوننت AboutComponent را نمایش خواهد داد.

نگهداری تاریخچه مرورگر

Angular Router همچنین تاریخچه مرورگر را مدیریت می‌کند. به این معنی که با هر تغییر مسیر، URL در نوار آدرس مرورگر به‌طور خودکار به‌روز می‌شود، اما بدون اینکه صفحه به‌طور کامل بارگذاری شود. این ویژگی باعث می‌شود که تجربه کاربری بسیار سریع‌تر و روان‌تر باشد.

برای مثال:

وقتی کاربر از مسیر ‘/home’ به مسیر ‘/about’ تغییر می‌کند، URL به‌روز می‌شود اما صفحه دوباره بارگذاری نمی‌شود.
کاربر می‌تواند با استفاده از دکمه‌های «بازگشت» و «جلو» در مرورگر، به راحتی بین مسیرها جابجا شود.

مفهوم Routing متناسب با URL

در Angular، مسیریابی به URLهایی که در نوار آدرس مرورگر ظاهر می‌شود متصل است. با استفاده از این ویژگی، می‌توانید مسیریابی‌های پیچیده‌ای را در اپلیکیشن خود پیاده‌سازی کنید که به URLهای خاص مرتبط است. این روش به اپلیکیشن‌های پیچیده کمک می‌کند که به راحتی قابلیت پیمایش (Navigation) بین صفحات مختلف را فراهم کنند.

مثال:

URL http://example.com/about به مسیر ‘about’ مرتبط است.
URL http://example.com/products/123 به مسیر ‘products/:id’ که یک مسیر پویا است، متصل می‌شود. در این حالت، پارامتر id می‌تواند هر مقداری (مانند عدد یا رشته) باشد که در مسیر وارد می‌شود.

مسیریابی و ناوبری (Routing) در Angular به شما این امکان را می‌دهد که اپلیکیشن‌های پیچیده و قابل پیمایش بسازید که کاربران بتوانند به راحتی بین صفحات مختلف جابجا شوند. این فرآیند نه تنها با مدیریت URLها و کامپوننت‌ها انجام می‌شود، بلکه ابزارهای مختلفی مانند Guards، Lazy Loading و Resolvers به شما این امکان را می‌دهند که قابلیت‌های بیشتری را به اپلیکیشن خود اضافه کنید.

ایجاد مسیرها با RouterModule

RouterModule در Angular ابزار اصلی برای مدیریت مسیریابی است. استفاده از این ماژول به شما این امکان را می‌دهد که مسیرهای مختلف را برای اپلیکیشن خود تعریف کرده و برای هر مسیر، یک کامپوننت خاص را بارگذاری کنید. در این بخش، مراحل استفاده از RouterModule برای ایجاد مسیرها و پیاده‌سازی مسیریابی در اپلیکیشن Angular را توضیح می‌دهیم.

مراحل ایجاد مسیرها با RouterModule

برای شروع پیاده‌سازی مسیریابی، باید مراحل زیر را دنبال کنید:

1. وارد کردن RouterModule

اولین قدم، وارد کردن RouterModule در ماژول اصلی اپلیکیشن (معمولاً app.module.ts) است. این ماژول به شما این امکان را می‌دهد که مسیرهای خود را در اپلیکیشن تنظیم کرده و از آن‌ها استفاده کنید.

2. تعریف مسیرها با استفاده از Routes

مسیریابی در Angular با استفاده از آرایه‌ای به نام Routes انجام می‌شود. در این آرایه، مسیرها و کامپوننت‌های مربوطه را مشخص می‌کنید. هر مسیر یک شیء است که حداقل دو ویژگی اصلی دارد:

path: که URL مربوط به مسیر را مشخص می‌کند.
component: که کامپوننتی را که باید برای آن مسیر بارگذاری شود، مشخص می‌کند.

3. استفاده از RouterModule.forRoot()

برای فعال‌سازی مسیریابی در اپلیکیشن، باید مسیرها را با استفاده از متد RouterModule.forRoot() به Angular معرفی کنید. این متد مسیرها را به سیستم مسیریابی Angular اضافه کرده و باعث می‌شود که آن‌ها در اپلیکیشن قابل استفاده شوند.

4. استفاده از routerLink در قالب

برای هدایت کاربران به مسیرهای مختلف، باید از دستور routerLink در قالب‌های HTML استفاده کنید. این دستور به Angular می‌گوید که کاربر را به مسیر مشخص‌شده هدایت کند.
مثال عملی:

در این مثال، دو مسیر اصلی تعریف می‌شود: یک مسیر پیش‌فرض (خانه) و یک مسیر برای صفحه «درباره ما».

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  { path: '', component: HomeComponent },  // مسیر پیش‌فرض
  { path: 'about', component: AboutComponent }  // مسیر برای صفحه "درباره ما"
];

@NgModule({
  declarations: [AppComponent, HomeComponent, AboutComponent],
  imports: [BrowserModule, RouterModule.forRoot(routes)],  // فعال‌سازی مسیریابی
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

توضیحات بخش‌های مختلف کد:

const routes: Routes = […]: در این بخش، مسیرها تعریف می‌شوند. هر مسیر یک شیء با دو ویژگی اصلی دارد: path و component.
مسیر ” (مسیر پیش‌فرض) به کامپوننت HomeComponent ارجاع می‌دهد.
مسیر ‘about’ به کامپوننت AboutComponent ارجاع می‌دهد.

RouterModule.forRoot(routes): در این بخش، مسیرهایی که در آرایه routes تعریف شده‌اند، به سیستم مسیریابی Angular معرفی می‌شوند.

declarations: در این بخش، تمامی کامپوننت‌های استفاده‌شده در اپلیکیشن (مانند HomeComponent و AboutComponent) اعلام می‌شوند.

imports: در این بخش، ماژول‌هایی که برای اپلیکیشن نیاز است وارد می‌شوند. BrowserModule برای ایجاد اپلیکیشن در مرورگر استفاده می‌شود و RouterModule.forRoot(routes) مسیریابی را فعال می‌کند.

5. استفاده از routerLink برای مسیریابی

بعد از تعریف مسیرها، می‌توانید از دستور routerLink در قالب‌های HTML برای هدایت کاربران به مسیرهای مختلف استفاده کنید. این دستور به طور خودکار مسیرهای شما را با URLهای مربوطه مرتبط می‌کند.

مثال استفاده از routerLink:

<a routerLink="/">Home</a>
<a routerLink="/about">About</a>

در این مثال:

لینک Home کاربر را به مسیر پیش‌فرض (”) هدایت می‌کند که کامپوننت HomeComponent را بارگذاری می‌کند.
لینک About کاربر را به مسیر ‘about’ هدایت می‌کند که کامپوننت AboutComponent را بارگذاری می‌کند.

6. نمایش کامپوننت‌ها با <router-outlet>

برای نمایش کامپوننت‌های مربوطه در هنگام تغییر مسیر، باید از <router-outlet> در قالب اصلی اپلیکیشن استفاده کنید. این تگ به Angular می‌گوید که در این نقطه از صفحه باید کامپوننت مربوطه به مسیر بارگذاری شده نمایش داده شود.

مثال:

<router-outlet></router-outlet>

این تگ باید در فایل app.component.html قرار گیرد. هنگامی که کاربر یکی از لینک‌های مسیریابی را انتخاب می‌کند، Angular کامپوننت مربوطه را در محل <router-outlet> نمایش می‌دهد.
استفاده از RouterModule در Angular یکی از اولین گام‌ها برای پیاده‌سازی مسیریابی در اپلیکیشن است. این ماژول به شما اجازه می‌دهد که مسیرهای مختلفی را برای اپلیکیشن خود تعریف کرده و کامپوننت‌های مربوط به هر مسیر را بارگذاری کنید. با استفاده از routerLink و <router-outlet>, می‌توانید ناوبری بین بخش‌های مختلف اپلیکیشن خود را به راحتی مدیریت کنید.

تعریف مسیرهای پویا و پارامترها

در Angular، مسیریابی پویا به شما این امکان را می‌دهد که مسیرهایی را ایجاد کنید که بخشی از URL آن‌ها متغیر باشند. این به شما اجازه می‌دهد که اطلاعات مختلفی را از URL استخراج کرده و آن‌ها را در کامپوننت‌ها و خدمات خود استفاده کنید. مسیرهای پویا معمولاً با استفاده از پارامترهایی در URL تعریف می‌شوند که مقادیر آن‌ها در هنگام درخواست تغییر می‌کنند.

مفهوم مسیرهای پویا و پارامترها

مسیر پویا (Dynamic Route) مسیری است که به طور کلی از یک قالب ثابت استفاده می‌کند، اما در بخشی از URL، پارامترهایی دارد که به هنگام درخواست تغییر می‌کنند. این پارامترها می‌توانند مقادیر مختلفی مانند شناسه‌ها (ID)، نام‌ها، تاریخ‌ها و یا هر اطلاعات دیگری باشند که نیاز دارید در کامپوننت‌ها استفاده کنید.

در Angular، می‌توان این پارامترها را با استفاده از نحوه تعریف مسیرها به صورت زیر ایجاد کرد:

نحوه تعریف مسیر پویا

برای ایجاد یک مسیر پویا، شما می‌توانید پارامترهای متغیر را با استفاده از : در مسیر تعریف کنید. این کار به Angular اجازه می‌دهد که مقادیری را از URL دریافت کند و آن‌ها را به عنوان پارامتر به کامپوننت‌های مختلف ارسال کند.

مثال:

const routes: Routes = [
  { path: 'user/:id', component: UserComponent }
];

در این مثال، :id یک پارامتر پویا است که به عنوان شناسه کاربر عمل می‌کند. به جای مقدار :id می‌توانید هر مقداری را وارد کنید و Angular این مقدار را به کامپوننت مربوطه ارسال می‌کند.

دریافت پارامترها در کامپوننت

برای دریافت پارامترهای پویا در کامپوننت، باید از ActivatedRoute استفاده کنید. ActivatedRoute به شما امکان می‌دهد که به پارامترهای مسیر دسترسی پیدا کرده و آن‌ها را در کامپوننت خود استفاده کنید.

استفاده از ActivatedRoute برای دریافت پارامترها

وارد کردن ActivatedRoute

برای استفاده از ActivatedRoute, شما باید آن را در کانستراکتور کامپوننت خود وارد کرده و از آن برای دسترسی به پارامترهای URL استفاده کنید.

اشتراک‌گذاری اطلاعات با paramMap

برای دریافت پارامترهای مسیر، از paramMap که در ActivatedRoute قرار دارد، استفاده می‌کنید. paramMap به شما این امکان را می‌دهد که به پارامترهای URL دسترسی پیدا کنید.

کد مثال:

import { ActivatedRoute } from '@angular/router';

export class UserComponent {
  userId: string;

  constructor(private route: ActivatedRoute) {
    // اشتراک‌گذاری پارامترها با استفاده از paramMap
    this.route.paramMap.subscribe(params => {
      this.userId = params.get('id');  // دریافت مقدار پارامتر 'id'
    });
  }
}

در این مثال:

this.route.paramMap.subscribe(…) به شما این امکان را می‌دهد که به پارامترهای مسیر دسترسی پیدا کرده و مقدار پارامتر id را دریافت کنید.
params.get(‘id’) مقدار پارامتر id را که در URL موجود است، می‌گیرد و در متغیر userId ذخیره می‌کند.

استفاده از پارامترهای چندگانه در مسیر

در صورتی که نیاز به استفاده از چند پارامتر داشته باشید، می‌توانید مسیر خود را با چند پارامتر پویا طراحی کنید. به عنوان مثال، فرض کنید بخواهید مسیرهای مختلفی برای کاربران و محصولات تعریف کنید که هرکدام شامل یک شناسه‌ی متفاوت باشند.

مثال:

const routes: Routes = [
  { path: 'user/:userId/product/:productId', component: ProductComponent }
];

در اینجا، userId و productId دو پارامتر پویا هستند که مقادیر آن‌ها به صورت جداگانه از URL دریافت می‌شوند.

برای دسترسی به این پارامترها در کامپوننت می‌توانید به صورت زیر عمل کنید:

import { ActivatedRoute } from '@angular/router';

export class ProductComponent {
  userId: string;
  productId: string;

  constructor(private route: ActivatedRoute) {
    this.route.paramMap.subscribe(params => {
      this.userId = params.get('userId');     // دریافت پارامتر userId
      this.productId = params.get('productId'); // دریافت پارامتر productId
    });
  }
}

در این مثال:

هر دو پارامتر userId و productId از URL استخراج شده و در کامپوننت ذخیره می‌شوند.

استفاده از Query Parameters

علاوه بر مسیرهای پویا، Angular به شما این امکان را می‌دهد که پارامترهای Query String (پارامترهای موجود در URL بعد از علامت ?) را نیز دریافت کنید.

مثال:

const routes: Routes = [
  { path: 'search', component: SearchComponent }
];

اگر URL به شکل زیر باشد:

/search?term=angular&page=1

برای دسترسی به پارامترهای term و page در کامپوننت SearchComponent, می‌توانید از ActivatedRoute استفاده کنید.

کد مثال:

import { ActivatedRoute } from '@angular/router';

export class SearchComponent {
  searchTerm: string;
  page: number;

  constructor(private route: ActivatedRoute) {
    this.route.queryParamMap.subscribe(params => {
      this.searchTerm = params.get('term');
      this.page = +params.get('page');  // تبدیل مقدار به عدد
    });
  }
}

تعریف مسیرهای پویا در Angular این امکان را می‌دهد که با استفاده از پارامترهای URL، مسیرهای خود را انعطاف‌پذیرتر کنید و به شما اجازه می‌دهد تا اطلاعات داینامیک را از URL دریافت کنید. این ویژگی در مواقعی که نیاز دارید اطلاعاتی مانند شناسه‌ها یا فیلترهای مختلف را از URL استخراج کرده و در کامپوننت‌های خود استفاده کنید، بسیار کاربردی است.

ویژگی‌های پیشرفته Routing: Lazy Loading

Lazy Loading یکی از ویژگی‌های بسیار مفید و پیشرفته در Angular است که به شما این امکان را می‌دهد تا ماژول‌ها را به صورت تنبل (Lazy) بارگذاری کنید. این ویژگی به طور قابل توجهی می‌تواند عملکرد اپلیکیشن را بهبود بخشد و زمان بارگذاری اولیه را کاهش دهد. در این بخش به جزئیات بیشتر در مورد Lazy Loading و چگونگی استفاده از آن در Angular می‌پردازیم.

مفهوم Lazy Loading

Lazy Loading در واقع به معنی بارگذاری تنبل است، به این معنا که ماژول‌ها و کدها تنها زمانی که به آن‌ها نیاز داریم، بارگذاری می‌شوند. این روش کمک می‌کند تا حجم اولیه اپلیکیشن شما کمتر شده و تنها زمانی که کاربر به بخش‌های خاصی از اپلیکیشن نیاز دارد، منابع مربوطه بارگذاری شوند. این ویژگی به طور خاص در اپلیکیشن‌های بزرگ و پیچیده مفید است که شامل بخش‌های مختلفی مانند بخش‌های کاربری، مدیریت و گزارش‌دهی هستند.

مزایای Lazy Loading

کاهش حجم بارگذاری اولیه: با استفاده از Lazy Loading، تنها کدهایی که برای نمایش اولین صفحه اپلیکیشن نیاز است، بارگذاری می‌شوند. این باعث کاهش زمان بارگذاری اولیه می‌شود.

افزایش عملکرد: بارگذاری تنبل باعث می‌شود که اپلیکیشن تنها ماژول‌های مورد نیاز را بارگذاری کند، بنابراین بار سرور کاهش می‌یابد و کاربر سریع‌تر به بخش‌های مختلف اپلیکیشن دسترسی پیدا می‌کند.

تقسیم کد: در Lazy Loading، شما می‌توانید اپلیکیشن خود را به ماژول‌های مختلف تقسیم کنید. این تقسیم کد به شما این امکان را می‌دهد که مدیریت بهتری روی کدهای پروژه داشته باشید و آن‌ها را به صورت مستقل بارگذاری کنید.

نحوه استفاده از Lazy Loading

برای استفاده از Lazy Loading در Angular، باید از ویژگی loadChildren در مسیرهای خود استفاده کنید. این ویژگی به شما امکان می‌دهد که یک ماژول خاص را به طور تنبل بارگذاری کنید.

گام اول: تعریف ماژول برای Lazy Loading

برای شروع، ابتدا یک ماژول جدید برای قسمت‌هایی که قصد دارید به صورت تنبل بارگذاری شوند، تعریف کنید. به عنوان مثال، فرض کنید ما یک ماژول به نام AdminModule داریم که مربوط به بخش مدیریت اپلیکیشن است.

ساخت ماژول Admin:

@NgModule({
  declarations: [AdminComponent],
  imports: [CommonModule],
})
export class AdminModule {}

گام دوم: استفاده از loadChildren در Routing

در مرحله بعد، شما باید این ماژول را در فایل app-routing.module.ts خود با استفاده از ویژگی loadChildren بارگذاری کنید. ویژگی loadChildren اجازه می‌دهد که ماژول مورد نظر تنها زمانی که کاربر به مسیر خاصی مراجعه کند، بارگذاری شود.

کد نمونه برای بارگذاری تنبل:

const routes: Routes = [
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
  }
];

در این مثال:

مسیر admin با استفاده از loadChildren به ماژول AdminModule اشاره می‌کند.
این ماژول تنها زمانی که کاربر به مسیر /admin وارد شود، بارگذاری خواهد شد.

گام سوم: پیاده‌سازی Route در ماژول‌های مختلف

ماژول‌هایی که از Lazy Loading استفاده می‌کنند معمولاً یک فایل routing جداگانه دارند که تمام مسیرهای مربوط به آن ماژول را مدیریت می‌کند. برای مثال، ماژول AdminModule ممکن است یک فایل admin-routing.module.ts برای تعریف مسیرهای خود داشته باشد.

کد نمونه برای Routing در ماژول Admin:

const adminRoutes: Routes = [
  { path: '', component: AdminDashboardComponent },
  { path: 'users', component: AdminUsersComponent }
];

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

در اینجا:

RouterModule.forChild(adminRoutes) برای افزودن مسیرهای مربوط به ماژول AdminModule استفاده می‌شود.
این مسیرها تنها زمانی بارگذاری خواهند شد که کاربر به مسیرهای مربوط به بخش مدیریت وارد شود.

Lazy Loading و عملکرد اپلیکیشن

Lazy Loading به طور مستقیم به عملکرد اپلیکیشن کمک می‌کند زیرا:

کاهش زمان بارگذاری اولیه: تنها فایل‌ها و ماژول‌هایی که در ابتدا به آن‌ها نیاز است بارگذاری می‌شوند.
بهبود تجربه کاربری: کاربر از ابتدا یک تجربه سریع‌تر خواهد داشت، زیرا تنها کدهای مورد نیاز بارگذاری می‌شوند.

نکات مهم هنگام استفاده از Lazy Loading

تقسیم کد به بخش‌های کوچک‌تر: برای بهره‌برداری کامل از Lazy Loading، بهتر است که اپلیکیشن خود را به ماژول‌های کوچک‌تری تقسیم کنید. این کار باعث می‌شود که تنها ماژول‌های ضروری بارگذاری شوند.

تنظیمات صحیح مسیرها: مسیرهایی که از Lazy Loading استفاده می‌کنند باید به درستی تعریف شوند تا به مشکلی در بارگذاری ماژول‌ها برخورد نکنید.

استفاده از Preloading Strategy: در صورتی که بخواهید بعضی از ماژول‌ها به طور پیش‌فرض بارگذاری شوند، می‌توانید از استراتژی پیش‌بارگذاری (Preloading) استفاده کنید که ماژول‌ها را به محض بارگذاری اپلیکیشن پیش‌بارگذاری می‌کند.

Lazy Loading یک ویژگی پیشرفته در Angular است که با کمک آن می‌توان ماژول‌ها را به صورت تنبل بارگذاری کرد و این باعث بهبود عملکرد و کاهش زمان بارگذاری اولیه اپلیکیشن می‌شود. با تقسیم کد به ماژول‌های مختلف و استفاده از ویژگی loadChildren، شما می‌توانید اپلیکیشن خود را بهینه کنید و تجربه کاربری بهتری ارائه دهید.

Guards برای حفاظت از مسیرها (CanActivate, CanDeactivate)

در Angular، Guards ابزارهایی هستند که به شما این امکان را می‌دهند تا از دسترسی به مسیرهای خاص جلوگیری کنید یا اقدامات خاصی را قبل از وارد شدن به یک مسیر انجام دهید. این ابزارها می‌توانند برای محافظت از مسیرها در برابر کاربران غیرمجاز، اعتبارسنجی قبل از تغییر صفحات یا بارگذاری داده‌های خاص استفاده شوند. از رایج‌ترین Guards ها در Angular می‌توان به CanActivate و CanDeactivate اشاره کرد.

مفهوم Guards در Angular

Guards به شما این امکان را می‌دهند که مسیرها را با توجه به شرایط خاص کنترل کنید. این شرایط می‌تواند شامل اعتبارسنجی کاربر، اطمینان از بارگذاری داده‌ها، یا جلوگیری از تغییر مسیرها باشد. در Angular، چندین نوع Guard وجود دارد که هر کدام وظیفه خاصی دارند:

CanActivate: بررسی می‌کند که آیا کاربر مجاز به دسترسی به مسیر خاصی است یا خیر.
CanDeactivate: قبل از ترک مسیر فعلی، به شما این امکان را می‌دهد که از کاربر بخواهید تغییرات خود را ذخیره کند یا از رفتن به مسیر جدید جلوگیری کنید.
CanLoad: قبل از بارگذاری ماژول با Lazy Loading، بررسی می‌کند که آیا کاربر مجاز به بارگذاری آن است یا خیر.
Resolve: قبل از ورود به مسیر، داده‌ها را بارگذاری می‌کند.

در اینجا به تفصیل به CanActivate و CanDeactivate می‌پردازیم.
CanActivate

CanActivate به شما این امکان را می‌دهد که قبل از وارد شدن به یک مسیر، بررسی کنید که آیا کاربر مجاز به مشاهده آن است یا خیر. به طور معمول از این Guard برای محافظت از مسیرهای حساس مانند بخش‌های حساب کاربری یا مدیریت استفاده می‌شود.
مثال استفاده از CanActivate:

فرض کنید می‌خواهید از ورود به مسیر “پروفایل” برای کاربرانی که وارد نشده‌اند جلوگیری کنید. برای این کار، می‌توانید یک Guard به نام AuthGuard بسازید که بررسی کند آیا کاربر وارد شده است یا خیر.

ساخت AuthGuard:

import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const isAuthenticated = // logic for checking authentication;

    if (!isAuthenticated) {
      // اگر کاربر وارد نشده است، او را به صفحه ورود هدایت می‌کنیم
      this.router.navigate(['/login']);
      return false; // جلوگیری از دسترسی به مسیر
    }

    return true; // اجازه دسترسی به مسیر
  }
}

در این مثال:

AuthGuard بررسی می‌کند که آیا کاربر وارد شده است یا خیر.
اگر کاربر وارد نشده باشد، او را به صفحه ورود هدایت می‌کند و از دسترسی به مسیر جلوگیری می‌کند.

استفاده از CanActivate در مسیر:

const routes: Routes = [
  {
    path: 'profile',
    component: ProfileComponent,
    canActivate: [AuthGuard] // اضافه کردن AuthGuard به مسیر
  }
];

در اینجا، اگر کاربر وارد نشده باشد، اجازه دسترسی به مسیر “پروفایل” را نخواهد داشت و به صفحه ورود هدایت می‌شود.
CanDeactivate

CanDeactivate این امکان را می‌دهد که قبل از ترک یک مسیر یا کامپوننت، بررسی کنید که آیا کاربر می‌خواهد تغییرات خود را ذخیره کند یا نه. به طور معمول از این Guard برای جلوگیری از از دست رفتن داده‌ها یا درخواست تایید از کاربر قبل از ترک صفحه استفاده می‌شود.
مثال استفاده از CanDeactivate:

فرض کنید کاربر در یک فرم تغییرات ایجاد کرده است و شما می‌خواهید قبل از ترک صفحه از او بپرسید که آیا می‌خواهد تغییرات خود را ذخیره کند.

ساخت CanDeactivate Guard:

import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';

export interface CanComponentDeactivate {
  canDeactivate: () => boolean | Promise<boolean>;
}

@Injectable({
  providedIn: 'root'
})
export class UnsavedChangesGuard implements CanDeactivate<CanComponentDeactivate> {
  canDeactivate(component: CanComponentDeactivate): boolean | Promise<boolean> {
    return component.canDeactivate ? component.canDeactivate() : true;
  }
}

در اینجا، CanComponentDeactivate یک رابط است که در کامپوننت‌هایی که نیاز به تایید دارند، پیاده‌سازی می‌شود. این کامپوننت باید متدی به نام canDeactivate داشته باشد که تصمیم می‌گیرد آیا اجازه تغییر مسیر به کاربر داده شود یا خیر.

پیاده‌سازی در کامپوننت:

@Component({
  selector: 'app-edit-profile',
  templateUrl: './edit-profile.component.html'
})
export class EditProfileComponent implements CanComponentDeactivate {
  // سایر کدهای کامپوننت

  canDeactivate(): boolean {
    if (this.form.dirty) {
      return confirm('Are you sure you want to leave without saving your changes?');
    }
    return true;
  }
}

در اینجا:

اگر فرم تغییراتی داشته باشد (یعنی کاربر تغییرات را ذخیره نکرده باشد)، از کاربر سوال می‌شود که آیا می‌خواهد بدون ذخیره‌سازی تغییرات، صفحه را ترک کند.

استفاده از CanDeactivate در مسیر:

const routes: Routes = [
  {
    path: 'edit-profile',
    component: EditProfileComponent,
    canDeactivate: [UnsavedChangesGuard]
  }
];

در اینجا، قبل از ترک مسیر “ویرایش پروفایل”، Guard بررسی می‌کند که آیا کاربر تغییرات ذخیره‌نشده دارد یا خیر.

Guards در Angular ابزارهای قدرتمندی هستند که به شما کمک می‌کنند تا مسیریابی را با امنیت بیشتر مدیریت کنید. با استفاده از CanActivate می‌توانید دسترسی به مسیرها را محدود کنید و با استفاده از CanDeactivate از از دست رفتن داده‌ها جلوگیری کنید. این ویژگی‌ها به شما کمک می‌کنند تا یک اپلیکیشن ایمن و کاربرپسند ایجاد کنید.

Resolvers برای بارگذاری داده‌ها قبل از ورود به مسیر

Resolvers در Angular ابزاری هستند که به شما این امکان را می‌دهند که داده‌ها را قبل از بارگذاری یک کامپوننت بارگذاری کنید. این ویژگی برای اپلیکیشن‌هایی که نیاز دارند داده‌ها را از سرور بارگذاری کرده و سپس مسیر مورد نظر را نمایش دهند، بسیار مفید است. با استفاده از Resolvers، می‌توانید از بارگذاری کامپوننت تا زمانی که داده‌های مورد نیاز آن آماده نشده‌اند، جلوگیری کنید. این باعث بهبود تجربه کاربری می‌شود زیرا کاربر از مشاهده یک صفحه خالی یا یک صفحه در حال بارگذاری جلوگیری می‌شود.

مفهوم Resolvers

یک Resolver در واقع یک سرویس است که با استفاده از متد resolve داده‌ها را بارگذاری کرده و سپس به مسیر هدایت می‌کند. این داده‌ها معمولاً از یک سرویس API یا پایگاه داده دریافت می‌شوند. هنگامی که کاربر به مسیری که دارای یک Resolver است وارد می‌شود، Angular ابتدا داده‌ها را بارگذاری کرده و تنها زمانی که داده‌ها آماده شدند، کامپوننت مقصد را بارگذاری می‌کند.

این قابلیت در مواقعی مفید است که شما نیاز دارید مطمئن شوید که داده‌های مورد نیاز برای نمایش به کاربر در دسترس هستند. به عنوان مثال، در صفحات داشبورد، پروفایل کاربری یا صفحات نمایش جزئیات یک شیء، ممکن است نیاز به بارگذاری داده‌ها قبل از نمایش اطلاعات داشته باشید.

نحوه استفاده از Resolver در Angular

برای استفاده از یک Resolver، باید ابتدا یک سرویس ایجاد کنید که از Resolve اینترفیس Angular پیروی کند. در این سرویس، متد resolve را پیاده‌سازی می‌کنید تا داده‌ها را بارگذاری کند.

مثال ایجاد Resolver:

ابتدا یک سرویس Resolver می‌سازیم که داده‌ها را از یک سرویس یا API بارگذاری کند.

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { DataService } from './data.service'; // فرض کنید یک سرویس برای دریافت داده‌ها داریم

@Injectable({
  providedIn: 'root'
})
export class DataResolver implements Resolve<any> {
  constructor(private dataService: DataService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // فرض کنید در اینجا از یک سرویس برای دریافت داده‌ها از API استفاده می‌کنیم
    return this.dataService.getData();
  }
}

در اینجا:

DataResolver یک سرویس است که داده‌ها را از سرویس DataService دریافت می‌کند.
متد resolve داده‌ها را قبل از بارگذاری کامپوننت دریافت می‌کند و به Angular می‌گوید که تا زمانی که داده‌ها آماده نشوند، مسیریابی را ادامه ندهد.

سپس این Resolver را به مسیر خود اضافه می‌کنید.

مثال استفاده از Resolver در مسیر:

import { Routes } from '@angular/router';
import { DataComponent } from './data/data.component';
import { DataResolver } from './data-resolver.service';

const routes: Routes = [
  {
    path: 'data',
    component: DataComponent,
    resolve: { data: DataResolver } // اضافه کردن Resolver به مسیر
  }
];

در اینجا:

زمانی که کاربر به مسیر data وارد می‌شود، Angular ابتدا داده‌ها را از DataResolver بارگذاری می‌کند.
پس از اینکه داده‌ها به طور کامل دریافت شدند، کامپوننت DataComponent بارگذاری می‌شود و داده‌ها به کامپوننت منتقل می‌شوند.

در کامپوننت مقصد (در اینجا DataComponent)، می‌توانید داده‌های بارگذاری شده را از ActivatedRoute دریافت کنید.

مثال دریافت داده‌ها در کامپوننت:

import { Routes } from '@angular/router';
import { DataComponent } from './data/data.component';
import { DataResolver } from './data-resolver.service';

const routes: Routes = [
  {
    path: 'data',
    component: DataComponent,
    resolve: { data: DataResolver } // اضافه کردن Resolver به مسیر
  }
];

در اینجا:

داده‌های بارگذاری شده توسط DataResolver از طریق this.route.snapshot.data[‘data’] در کامپوننت DataComponent در دسترس قرار می‌گیرد.

مزایای استفاده از Resolvers

بارگذاری داده‌ها قبل از نمایش کامپوننت: با استفاده از Resolvers، می‌توانید اطمینان حاصل کنید که داده‌های مورد نیاز برای نمایش به کاربر در دسترس هستند. این به شما کمک می‌کند تا از نمایش صفحات خالی یا ناقص جلوگیری کنید.
کاهش بارهای نامناسب: اگر یک کامپوننت نیاز به داده‌های خاصی دارد، می‌توانید آن را با استفاده از Resolver مدیریت کنید تا بارگذاری داده‌ها تنها زمانی صورت گیرد که کامپوننت در حال نمایش است.
بهبود تجربه کاربری: با استفاده از Resolvers، کاربر تجربه بهتری خواهد داشت زیرا همیشه با صفحات بارگذاری شده و بدون خطا مواجه می‌شود.

Resolvers در Angular ابزاری بسیار مفید برای بارگذاری داده‌ها قبل از ورود به یک مسیر هستند. این ویژگی به شما کمک می‌کند تا داده‌های مورد نیاز را به صورت همزمان با بارگذاری مسیر بارگذاری کنید و تجربه کاربری بهتری ایجاد کنید. استفاده از Resolvers برای صفحات حساس و مهم که نیاز به داده‌ها از سرور دارند، بسیار مناسب است.

نتیجه‌گیری

مسیریابی و ناوبری (Routing) در Angular ابزاری قدرتمند برای مدیریت مسیرها و هدایت کاربران به بخش‌های مختلف اپلیکیشن است. از طریق استفاده از RouterModule، می‌توان مسیرهای ثابت و پویا را تعریف کرد و با استفاده از ویژگی‌های پیشرفته‌ای مانند Lazy Loading، Guards، و Resolvers، عملکرد اپلیکیشن را بهبود بخشید. این ویژگی‌ها نه تنها به کاهش حجم اپلیکیشن و بهبود عملکرد کمک می‌کنند، بلکه تجربه کاربری بهتری را از طریق بارگذاری داده‌ها قبل از نمایش کامپوننت‌ها و مدیریت دسترسی به مسیرها فراهم می‌آورند. با تسلط بر مفهوم مسیریابی و ناوبری (Routing) در Angular، می‌توانید اپلیکیشن‌هایی قدرتمند و کاربرپسند بسازید که هم از نظر سرعت و هم از نظر امنیت بهینه‌شده باشند.

آموزش مسیریابی و ناوبری (Routing) در Angula

دیدگاه های شما

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *