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为什么要区别组件服务?
一个重要的原因就是它希望,数据展示逻辑
与 数据访问逻辑
是拆分开的,组件需要在页面展示的数据就委托为某个服务去取!以此使代码得到高复用。