文章目錄
-
- 1 前言
- 2 HttpClientModule
- 3 封裝http
- 4 細節
- 5 使用
- 6 總結
1 前言
最近一直在用angular8,就在部落格這裡分享一下如何封裝http服務。
2 HttpClientModule
要在angular裡使用http服務必須先在裡導入
app.module.ts
子產品,不然會報錯。
HttpClientModule
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
// 導入關鍵子產品
import { HttpClientModule } from '@angular/common/http';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule { }
3 封裝http
根據angular的官網,請求傳回的是資料的 Observable
對象,是以元件要訂閱(subscribe) 該方法的傳回值。
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class HttpService {
private http: any;
constructor(private Http: HttpClient) {
this.http = Http;
}
// get方法
public get(url: string, options?: Object, params?: Object): Observable<{}> {
let httpParams = new HttpParams();
if (params) {
for (const key in params) {
if (params[key] === false || params[key]) {
httpParams = httpParams.set(key, params[key]);
}
}
}
return this.http.get(url, { headers: options, params: httpParams }).pipe(catchError(this.handleError));
}
// post方法
public post(url: string, body: any = null, options?: Object): Observable<{}> {
return this.http.post(url, body, options).pipe(catchError(this.handleError));
}
// post表單
public postForm(url: string, body: any = null, options?: Object): Observable<{}> {
let httpParams = new HttpParams();
if (body) {
for (const key in body) {
if (body[key] === false || body[key]) {
httpParams = httpParams.set(key, body[key]);
}
}
}
return this.http.post(url, httpParams, options).pipe(catchError(this.handleError));
}
/**
* 處理請求失敗的錯誤
* @param error HttpErrorResponse
*/
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error('An error occurred:', error.error.message);
} else {
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
console.log(error);
return throwError(error.error);
}
}
這裡貼上
get、post
兩種的方式的例子,其他如delete這些就不展示了,一樣的原理。
4 細節
稍微說一下裡面的細節: return this.http.post(url, httpParams, options).pipe(catchError(this.handleError));
這裡傳回的是
Observable<{}>
,并通過pipe管道處理請求異常,異常的處理在最下面的
handleError
方法裡。
5 使用
// 引入封裝好的http服務
constructor(private http: HttpService) { }
/**
* 測試get方法
* @param successCallback 成功的回調
* @param failCallback 失敗的回調
*/
public testGet(url: string, successCallback?: Function, failCallback?: Function) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json; charset=UTF-8'
})
};
this.http.get(url, httpOptions.headers).subscribe(
(res: any) => {
successCallback(res); // 成功走sucessCallback
}, (err: HttpErrorResponse) => {
failCallback(err); // 失敗
}
);
}
這是一個具體的get請求service,
testGet
定義裡三個參數,一個是請求位址,還有成功的回調與失敗的回掉。
subscribe訂閱observable 對象。
在component裡使用 this.testService.testGet('url', (res:any) => {}, (err:any) =>{});
6 總結
angular封裝http請求并不難,官網也講得比較清楚。
個人認為最重要的還是這種
封裝服務
的思想,而angular為什麼要差別元件服務?
一個重要的原因就是它希望,
資料展示邏輯
與
資料通路邏輯
是拆分開的,元件需要在頁面展示的資料就委托為某個服務去取!以此使代碼得到高複用。