您好,登錄后才能下訂單哦!
為什么要封裝呢?
angular4自身提供的請求方法是用Observable來實現的。用的是觀察者模式,個人認為這用來寫請求是非常方便的。
一個項目里會有非常多的不同的請求,但是其實每個請求都會有些共性。比如:每個請求都要傳Authorization,比如每個請求都要先判斷后臺返回的status字段為200時才是請求成功,后臺正真返回的數據在data字段里,比如對于錯誤信息的處理都是一樣的......等等。
所以我們需要封裝出一個請求,去統一處理這些問題,從而保證組件里調用請求方法的時候收到的值都是可以直接拿來用的,幾乎不用再寫些重復的代碼。
希望封裝成什么樣呢?
當然是越少重復的代碼越好,我們就是想偷懶!!!!
怎么實現呢?
首先先新建一個請求的service,文件名為:request.service.ts。然后跟著我來虛擬需求,一步一步的慢慢來完善這個service。
需求A
1.請求方式為get。
2.默認的請求超時時間為3秒,可傳入別的超時時間。
3.后臺返回的成功的json為這樣:
{ "status": 200, "data" : ... }
錯誤時這樣:
{ "status": 201, "msg" : "用戶名或密碼錯誤" }
實現A
request.service.ts
/** ******************************************************************************************** * @App: test * @author: isiico * @type: service * @src: services/request.service.ts * * @descriptions: * 請求的服務 * ******************************************************************************************** */ // Angular Core import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; // rxjs import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import 'rxjs/add/observable/throw'; @Injectable() export class RequestService { private setTimeout = 3000; // 默認的超時時間 constructor(private http:HttpClient) { } /** 獲取數據 * param: url string 必填,請求的url * time number 可不填,請求的超時時間,如不填,默認為setTimeout * return: Observable HttpClient的get請求,請求完成后返回的值類型是any **/ public getData(url, time = this.setTimeout):Observable<any> { let thiUrl = url; // 用到的url let thisTime = time; // 用到的超時時間 return this.http.get(thiUrl) .timeout(thisTime) .map(res => this.resFun(res)); } /** 返回數據的處理 * param: data any 必填,需要處理的數據 * return: res any 返回處理后的值 **/ private resFun(data:any):any { let thisData:any = data; // 需要處理的值 let res:any; // 最終值 // 當status為200時 if (thisData['status'] == 200) { res = thisData['data']; // 給最終值賦值 } else { // 當status不為200時 let err = thisData['msg']; // 錯誤信息 throw new Error(err); // 拋出錯誤 } return res; // 返回最終值 } }
需求B
1.為了安全,后臺要求請求的頭需要加上Authorization參數。
2.當請求失敗(如404,500這種)時,處理好錯誤信息,最后的錯誤信息要像 實現A 里一樣,是可以直接用的字符串類型的錯誤信息。
實現B
request.service.ts (只展示新增的代碼,完整代碼后面有)
import 'rxjs/add/operator/catch'; @Injectable() export class RequestService { /** 添加Authorization的屬性 */ private addAuthorization(options:any):void { options['headers'] = { 'Authorization': '1drf5dg4d7s4w7z', }; } /** 獲取數據 * param: url string 必填,請求的url * time number 可不填,請求的超時時間,如不填,默認為setTimeout * return: Observable HttpClient的get請求,請求完成后返回的值類型是any **/ public getData(url, time = this.setTimeout):Observable<any> { let thiUrl = url; // 用到的url let options = {}; // 請求的設置 let thisTime = time; // 用到的超時時間 this.addAuthorization(options); // 請求頭里添加Authorization參數 return this.http.get(thiUrl, options) .timeout(thisTime) .catch(this.httpErrorFun) // 處理錯誤信息(必須放在timeout和map之間) .map(res => this.resFun(res)); } /** 對請求錯誤信息的處理 * param: err any 必填,需要處理的錯誤信息 * return: res string 處理后的結果 **/ public httpErrorFun(err:any):string { /* new */ let res:string = ''; // 處理后的結果 /* new */ let data:any = err; // 需要處理的值 /* new */ /** 后臺有返回錯誤信息時 */ if (data.hasOwnProperty('error') && data.hasOwnProperty('message')) { /* new */ res = data.message; /* new */ /** 后臺沒有返回錯誤信息只有錯誤名時 */ } else if (data.hasOwnProperty('name')) { /* new */ let errName = data.name; /* new */ /** 請求超時 */ if (errName == 'TimeoutError') { /* new */ res = '對不起,請求超時了'; /* new */ } /** 后臺返回未授權時 */ } else if (data == "Unauthorization") { /* new */ res = '您沒有權限,請重新登錄' /* new */ } else { res = "哎呀,不知道是啥錯誤~~"; /* new */ } return Observable.throw(res); /* new */ } }
完整的request service 代碼
request.service.ts
/** ******************************************************************************************** * @App: test * @author: isiico * @type: service * @src: services/request.service.ts * * @descriptions: * 請求的服務 * ******************************************************************************************** */ // Angular Core import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; // rxjs import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import 'rxjs/add/observable/throw'; import 'rxjs/add/operator/catch'; @Injectable() export class RequestService { private setTimeout:number = 3000; // 默認的超時時間 constructor(private http:HttpClient) { } /** 添加Authorization的屬性 */ private addAuthorization(options:any):void { options['headers'] = { 'Authorization': '1drf5dg4d7s4w7z', }; } /** 獲取數據 * param: url string 必填,請求的url * time number 可不填,請求的超時時間,如不填,默認為setTimeout * return: Observable HttpClient的get請求,請求完成后返回的值類型是any **/ public getData(url, time = this.setTimeout):Observable<any> { let thiUrl = url; // 用到的url let options = {}; // 請求的設置 let thisTime = time; // 用到的超時時間 this.addAuthorization(options); // 請求頭里添加Authorization參數 return this.http.get(thiUrl, options) .timeout(thisTime) .catch(this.httpErrorFun) // 處理錯誤信息(必須放在timeout和map之間) .map(res => this.resFun(res)); } /** 返回數據的處理 * param: data any 必填,需要處理的數據 * return: res any 返回處理后的值 **/ private resFun(data:any):any { let thisData:any = data; // 需要處理的值 let res:any; // 最終值 // 當status為200時 if (thisData['status'] == 200) { res = thisData['data']; // 給最終值賦值 } else { // 當status不為200時 let err = thisData['msg']; // 錯誤信息 throw new Error(err); // 拋出錯誤 } return res; // 返回最終值 } /** 對請求錯誤信息的處理 * param: err any 必填,需要處理的錯誤信息 * return: res string 處理后的結果 **/ public httpErrorFun(err:any):string { let res:string = ''; // 處理后的結果 let data:any = err; // 需要處理的值 /** 后臺有返回錯誤信息時 */ if (data.hasOwnProperty('error') && data.hasOwnProperty('message')) { res = data.message; /** 后臺沒有返回錯誤信息只有錯誤名時 */ } else if (data.hasOwnProperty('name')) { let errName = data.name; /** 請求超時 */ if (errName == 'TimeoutError') { res = '對不起,請求超時了'; } /** 后臺返回未授權時 */ } else if (data == "Unauthorization") { res = '您沒有權限,請重新登錄'; } else { res = "哎呀,不知道是啥錯誤~~"; } return Observable.throw(res); } }
小結
至此,我們已經完成了一個滿足基本需求的,可以公共使用的請求服務,接下來我們來看怎么在組件內調用。
調用
我們有個叫list的組件,要調用get請求,請求成功顯示數據,請求失敗,顯示錯誤信息。
list.component.ts
/** ******************************************************************************************** * @App: test * @author: isiico * @type: component * @src: components/list.component.ts * * @descriptions: * list組件 * ******************************************************************************************** */ // Angular Core import { Component, OnInit } from '@angular/core'; // Services import { RequestService } from "../services/request.service"; @Component({ moduleId: module.id, templateUrl: 'list.component.html' }) export class ListComponent implements OnInit { listApi = '/assets/mock-data/list.json'; // 列表的api地址 list:Array<any>; // 列表數據(類型為數組) listErrMsg: string = ''; // 列表請求的錯誤信息 constructor(private req: RequestService) { } /** 獲取list */ getList(){ this.listErrMsg = ''; // 清空錯誤信息 // 發送請求 this.req.getData(this.cabinetListApi) .subscribe( res=>{ // 請求成功 this.cabinets = []; this.cabinets = res; },err=>{ // 請求失敗 this.cabinets = []; this.listErrMsg = err; }) } ngOnInit() { this.getList(); } }
頁面的顯示自己去完成吧!
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。