پیشتر در مورد HTTP Client جدید Angular، مطلب «ارتقاء به HTTP Client در Angular 4.3» را بررسی کردیم. یکی دیگر از قابلیتهای HttpClient که روش اصلی دسترسی به اطلاعات از راه دور در Angular 5 نیز میباشد، امکان تعریف Interceptors سفارشی برای آن است. به کمک Interceptors میتوان به تمامی درخواستهای HTTP ارسالی و پاسخهای دریافتی از سرور گوش فرا داد و در این بین منطق ویژهای را پیاده سازی کرد؛ مانندcaching ،logging و غیره. در مطلب جاری قصد داریم از این قابلیت برای نمایش یک loading bar مشخص کنندهی شروع و پایان تمامی درخواستهای HTTP استفاده کنیم.
دریافت و نصب پیشنیازها
برای نمایش loading bar در بالای صفحه، از کامپوننت ng2-slim-loading-bar استفاده خواهیم کرد. دمویی از آنرا در اینجا میتوانید مشاهده کنید.
برای نصب آن، ابتدا دستور ذیل را در ریشهی پروژه اجرا کنید:
پس از آن فایل angular-cli.json. را گشوده و فایل css آنرا تعریف نمائید:
در ادامه به فایل app.module.ts مراجعه کرد و ماژول آنرا نیز به نحو ذیل به برنامه معرفی کنید:
پس از این مقدمات، هرجایی که نیاز به استفادهی از آن با کدنویسی باشد، ابتدا سرویس SlimLoadingBarService آنرا به سازندهی کلاس کامپوننت مدنظر تزریق میکنیم و سپس از متدهای start ،stop و complete آن میتوان استفاده کرد.
همچنین برای نمایش این کامپوننت باید selector آن را در فایل app.component.html در بالای صفحه اضافه کرد:
تدارک یک LoaderInterceptor برای استفاده از ng2-slim-loading-bar
در ادامه میخواهیم هر زمانیکه در سراسر برنامه، درخواست HTTP ایی شروع شد، این کامپوننت نمایش داده شود و در پایان درخواست و یا درصورت بروز خطایی، پایان یابد و مخفی شود. برای این منظور یک Interceptor جدید را به صورت ذیل به پوشهی Core برنامه اضافه میکنیم:
با این کدها:
توضیحات:
- برای پیاده سازی یک interceptor جدید، نیاز است کلاس سرویسی را که HttpInterceptor را پیاده سازی میکند، ایجاد کنیم. برای تکمیل این پیاده سازی نیاز است متد intercept را با امضایی که مشاهده میکنید، تعریف کنیم:
- در اینجا پارامتر req به خود درخواست Http اشاره میکند.
- کار پارامتر next تنظیم و بازگشت یک HttpEvent observable توسط متد handle آن است.
برای نمونه در اینجا ابتدا سرویس SlimLoadingBarService به سازندهی کلاس interceptor تزریق شدهاست. سپس توسط آن میتوان به متدهای start و complete این کامپوننت دسترسی یافت. برای مثال در ابتدای کار گوش فرادادن به درخواست جاری، متد start فراخوانی شدهاست و سپس زمانیکه پاسخی از سرور دریافت شده و یا خطایی رخداده، متد complete آن فراخوانی شدهاست.
ثبت و معرفی LoaderInterceptorService به سیستم
برای معرفی interceptor تهیه شده، به فایل app.module.ts مراجعه کرد و قسمت providers آنرا به نحو ذیل تکمیل میکنیم:
آزمایش برنامه
اکنون اگر قسمتهای مختلف برنامه را که با HttpClient جدید کار میکنند بررسی کنید، متوجه خواهید شد که با شروع هر درخواست، loading bar قرمزی در بالای صفحه ظاهر میشود و در پایان درخواست، به صورت خودکار مخفی میگردد. نکتهی مهم این روش عدم نیاز به تغییری در قسمتهای مختلف برنامه است. این interceptor سراسری است و به صورت یکسانی بر روی کل برنامه تاثیر میگذارد.
دریافت و نصب پیشنیازها
برای نمایش loading bar در بالای صفحه، از کامپوننت ng2-slim-loading-bar استفاده خواهیم کرد. دمویی از آنرا در اینجا میتوانید مشاهده کنید.
برای نصب آن، ابتدا دستور ذیل را در ریشهی پروژه اجرا کنید:
npm install ng2-slim-loading-bar --save
"styles": [ "../node_modules/ng2-slim-loading-bar/style.css", "styles.css" ],
import {SlimLoadingBarModule} from 'ng2-slim-loading-bar'; @NgModule({ imports: [ //... SlimLoadingBarModule.forRoot() ] }) export class AppModule { }
پس از این مقدمات، هرجایی که نیاز به استفادهی از آن با کدنویسی باشد، ابتدا سرویس SlimLoadingBarService آنرا به سازندهی کلاس کامپوننت مدنظر تزریق میکنیم و سپس از متدهای start ،stop و complete آن میتوان استفاده کرد.
import {SlimLoadingBarService} from 'ng2-slim-loading-bar';
<ng2-slim-loading-bar></ng2-slim-loading-bar>
تدارک یک LoaderInterceptor برای استفاده از ng2-slim-loading-bar
در ادامه میخواهیم هر زمانیکه در سراسر برنامه، درخواست HTTP ایی شروع شد، این کامپوننت نمایش داده شود و در پایان درخواست و یا درصورت بروز خطایی، پایان یابد و مخفی شود. برای این منظور یک Interceptor جدید را به صورت ذیل به پوشهی Core برنامه اضافه میکنیم:
ng g s core/interceptors/LoaderInterceptor --spec false
import { Injectable } from "@angular/core"; import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http"; import { Observable } from "rxjs/Observable"; import "rxjs/add/operator/do"; import { SlimLoadingBarService } from "ng2-slim-loading-bar"; @Injectable() export class LoaderInterceptorService implements HttpInterceptor { constructor(private loadingBar: SlimLoadingBarService) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // start our loader here this.loadingBar.start(); return next.handle(req).do( (event: HttpEvent<any>) => { if (event instanceof HttpResponse) { this.loadingBar.complete(); } }, (err: any) => { this.loadingBar.complete(); }); } }
- برای پیاده سازی یک interceptor جدید، نیاز است کلاس سرویسی را که HttpInterceptor را پیاده سازی میکند، ایجاد کنیم. برای تکمیل این پیاده سازی نیاز است متد intercept را با امضایی که مشاهده میکنید، تعریف کنیم:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
- کار پارامتر next تنظیم و بازگشت یک HttpEvent observable توسط متد handle آن است.
برای نمونه در اینجا ابتدا سرویس SlimLoadingBarService به سازندهی کلاس interceptor تزریق شدهاست. سپس توسط آن میتوان به متدهای start و complete این کامپوننت دسترسی یافت. برای مثال در ابتدای کار گوش فرادادن به درخواست جاری، متد start فراخوانی شدهاست و سپس زمانیکه پاسخی از سرور دریافت شده و یا خطایی رخداده، متد complete آن فراخوانی شدهاست.
ثبت و معرفی LoaderInterceptorService به سیستم
برای معرفی interceptor تهیه شده، به فایل app.module.ts مراجعه کرد و قسمت providers آنرا به نحو ذیل تکمیل میکنیم:
@NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptorService, multi: true } ] }) export class AppModule {}
آزمایش برنامه
اکنون اگر قسمتهای مختلف برنامه را که با HttpClient جدید کار میکنند بررسی کنید، متوجه خواهید شد که با شروع هر درخواست، loading bar قرمزی در بالای صفحه ظاهر میشود و در پایان درخواست، به صورت خودکار مخفی میگردد. نکتهی مهم این روش عدم نیاز به تغییری در قسمتهای مختلف برنامه است. این interceptor سراسری است و به صورت یکسانی بر روی کل برنامه تاثیر میگذارد.