為什么要封裝呢?
站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到福鼎網(wǎng)站設(shè)計(jì)與福鼎網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站制作、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國(guó)際域名空間、虛擬主機(jī)、企業(yè)郵箱。業(yè)務(wù)覆蓋福鼎地區(qū)。
angular4自身提供的請(qǐng)求方法是用Observable來(lái)實(shí)現(xiàn)的。用的是觀察者模式,個(gè)人認(rèn)為這用來(lái)寫(xiě)請(qǐng)求是非常方便的。
一個(gè)項(xiàng)目里會(huì)有非常多的不同的請(qǐng)求,但是其實(shí)每個(gè)請(qǐng)求都會(huì)有些共性。比如:每個(gè)請(qǐng)求都要傳Authorization,比如每個(gè)請(qǐng)求都要先判斷后臺(tái)返回的status字段為200時(shí)才是請(qǐng)求成功,后臺(tái)正真返回的數(shù)據(jù)在data字段里,比如對(duì)于錯(cuò)誤信息的處理都是一樣的......等等。
所以我們需要封裝出一個(gè)請(qǐng)求,去統(tǒng)一處理這些問(wèn)題,從而保證組件里調(diào)用請(qǐng)求方法的時(shí)候收到的值都是可以直接拿來(lái)用的,幾乎不用再寫(xiě)些重復(fù)的代碼。
希望封裝成什么樣呢?
當(dāng)然是越少重復(fù)的代碼越好,我們就是想偷懶?。?!!
怎么實(shí)現(xiàn)呢?
首先先新建一個(gè)請(qǐng)求的service,文件名為:request.service.ts。然后跟著我來(lái)虛擬需求,一步一步的慢慢來(lái)完善這個(gè)service。
需求A
1.請(qǐng)求方式為get。
2.默認(rèn)的請(qǐng)求超時(shí)時(shí)間為3秒,可傳入別的超時(shí)時(shí)間。
3.后臺(tái)返回的成功的json為這樣:
{ "status": 200, "data" : ... }
錯(cuò)誤時(shí)這樣:
{ "status": 201, "msg" : "用戶名或密碼錯(cuò)誤" }
實(shí)現(xiàn)A
request.service.ts
/** ******************************************************************************************** * @App: test * @author: isiico * @type: service * @src: services/request.service.ts * * @descriptions: * 請(qǐng)求的服務(wù) * ******************************************************************************************** */ // 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; // 默認(rèn)的超時(shí)時(shí)間 constructor(private http:HttpClient) { } /** 獲取數(shù)據(jù) * param: url string 必填,請(qǐng)求的url * time number 可不填,請(qǐng)求的超時(shí)時(shí)間,如不填,默認(rèn)為setTimeout * return: Observable HttpClient的get請(qǐng)求,請(qǐng)求完成后返回的值類型是any **/ public getData(url, time = this.setTimeout):Observable{ let thiUrl = url; // 用到的url let thisTime = time; // 用到的超時(shí)時(shí)間 return this.http.get(thiUrl) .timeout(thisTime) .map(res => this.resFun(res)); } /** 返回?cái)?shù)據(jù)的處理 * param: data any 必填,需要處理的數(shù)據(jù) * return: res any 返回處理后的值 **/ private resFun(data:any):any { let thisData:any = data; // 需要處理的值 let res:any; // 最終值 // 當(dāng)status為200時(shí) if (thisData['status'] == 200) { res = thisData['data']; // 給最終值賦值 } else { // 當(dāng)status不為200時(shí) let err = thisData['msg']; // 錯(cuò)誤信息 throw new Error(err); // 拋出錯(cuò)誤 } return res; // 返回最終值 } }
需求B
1.為了安全,后臺(tái)要求請(qǐng)求的頭需要加上Authorization參數(shù)。
2.當(dāng)請(qǐng)求失?。ㄈ?04,500這種)時(shí),處理好錯(cuò)誤信息,最后的錯(cuò)誤信息要像 實(shí)現(xiàn)A 里一樣,是可以直接用的字符串類型的錯(cuò)誤信息。
實(shí)現(xiàn)B
request.service.ts (只展示新增的代碼,完整代碼后面有)
import 'rxjs/add/operator/catch'; @Injectable() export class RequestService { /** 添加Authorization的屬性 */ private addAuthorization(options:any):void { options['headers'] = { 'Authorization': '1drf5dg4d7s4w7z', }; } /** 獲取數(shù)據(jù) * param: url string 必填,請(qǐng)求的url * time number 可不填,請(qǐng)求的超時(shí)時(shí)間,如不填,默認(rèn)為setTimeout * return: Observable HttpClient的get請(qǐng)求,請(qǐng)求完成后返回的值類型是any **/ public getData(url, time = this.setTimeout):Observable{ let thiUrl = url; // 用到的url let options = {}; // 請(qǐng)求的設(shè)置 let thisTime = time; // 用到的超時(shí)時(shí)間 this.addAuthorization(options); // 請(qǐng)求頭里添加Authorization參數(shù) return this.http.get(thiUrl, options) .timeout(thisTime) .catch(this.httpErrorFun) // 處理錯(cuò)誤信息(必須放在timeout和map之間) .map(res => this.resFun(res)); } /** 對(duì)請(qǐng)求錯(cuò)誤信息的處理 * param: err any 必填,需要處理的錯(cuò)誤信息 * return: res string 處理后的結(jié)果 **/ public httpErrorFun(err:any):string { /* new */ let res:string = ''; // 處理后的結(jié)果 /* new */ let data:any = err; // 需要處理的值 /* new */ /** 后臺(tái)有返回錯(cuò)誤信息時(shí) */ if (data.hasOwnProperty('error') && data.hasOwnProperty('message')) { /* new */ res = data.message; /* new */ /** 后臺(tái)沒(méi)有返回錯(cuò)誤信息只有錯(cuò)誤名時(shí) */ } else if (data.hasOwnProperty('name')) { /* new */ let errName = data.name; /* new */ /** 請(qǐng)求超時(shí) */ if (errName == 'TimeoutError') { /* new */ res = '對(duì)不起,請(qǐng)求超時(shí)了'; /* new */ } /** 后臺(tái)返回未授權(quán)時(shí) */ } else if (data == "Unauthorization") { /* new */ res = '您沒(méi)有權(quán)限,請(qǐng)重新登錄' /* new */ } else { res = "哎呀,不知道是啥錯(cuò)誤~~"; /* new */ } return Observable.throw(res); /* new */ } }
完整的request service 代碼
request.service.ts
/** ******************************************************************************************** * @App: test * @author: isiico * @type: service * @src: services/request.service.ts * * @descriptions: * 請(qǐng)求的服務(wù) * ******************************************************************************************** */ // 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; // 默認(rèn)的超時(shí)時(shí)間 constructor(private http:HttpClient) { } /** 添加Authorization的屬性 */ private addAuthorization(options:any):void { options['headers'] = { 'Authorization': '1drf5dg4d7s4w7z', }; } /** 獲取數(shù)據(jù) * param: url string 必填,請(qǐng)求的url * time number 可不填,請(qǐng)求的超時(shí)時(shí)間,如不填,默認(rèn)為setTimeout * return: Observable HttpClient的get請(qǐng)求,請(qǐng)求完成后返回的值類型是any **/ public getData(url, time = this.setTimeout):Observable{ let thiUrl = url; // 用到的url let options = {}; // 請(qǐng)求的設(shè)置 let thisTime = time; // 用到的超時(shí)時(shí)間 this.addAuthorization(options); // 請(qǐng)求頭里添加Authorization參數(shù) return this.http.get(thiUrl, options) .timeout(thisTime) .catch(this.httpErrorFun) // 處理錯(cuò)誤信息(必須放在timeout和map之間) .map(res => this.resFun(res)); } /** 返回?cái)?shù)據(jù)的處理 * param: data any 必填,需要處理的數(shù)據(jù) * return: res any 返回處理后的值 **/ private resFun(data:any):any { let thisData:any = data; // 需要處理的值 let res:any; // 最終值 // 當(dāng)status為200時(shí) if (thisData['status'] == 200) { res = thisData['data']; // 給最終值賦值 } else { // 當(dāng)status不為200時(shí) let err = thisData['msg']; // 錯(cuò)誤信息 throw new Error(err); // 拋出錯(cuò)誤 } return res; // 返回最終值 } /** 對(duì)請(qǐng)求錯(cuò)誤信息的處理 * param: err any 必填,需要處理的錯(cuò)誤信息 * return: res string 處理后的結(jié)果 **/ public httpErrorFun(err:any):string { let res:string = ''; // 處理后的結(jié)果 let data:any = err; // 需要處理的值 /** 后臺(tái)有返回錯(cuò)誤信息時(shí) */ if (data.hasOwnProperty('error') && data.hasOwnProperty('message')) { res = data.message; /** 后臺(tái)沒(méi)有返回錯(cuò)誤信息只有錯(cuò)誤名時(shí) */ } else if (data.hasOwnProperty('name')) { let errName = data.name; /** 請(qǐng)求超時(shí) */ if (errName == 'TimeoutError') { res = '對(duì)不起,請(qǐng)求超時(shí)了'; } /** 后臺(tái)返回未授權(quán)時(shí) */ } else if (data == "Unauthorization") { res = '您沒(méi)有權(quán)限,請(qǐng)重新登錄'; } else { res = "哎呀,不知道是啥錯(cuò)誤~~"; } return Observable.throw(res); } }
小結(jié)
至此,我們已經(jīng)完成了一個(gè)滿足基本需求的,可以公共使用的請(qǐng)求服務(wù),接下來(lái)我們來(lái)看怎么在組件內(nèi)調(diào)用。
調(diào)用
我們有個(gè)叫l(wèi)ist的組件,要調(diào)用get請(qǐng)求,請(qǐng)求成功顯示數(shù)據(jù),請(qǐng)求失敗,顯示錯(cuò)誤信息。
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; // 列表數(shù)據(jù)(類型為數(shù)組) listErrMsg: string = ''; // 列表請(qǐng)求的錯(cuò)誤信息 constructor(private req: RequestService) { } /** 獲取list */ getList(){ this.listErrMsg = ''; // 清空錯(cuò)誤信息 // 發(fā)送請(qǐng)求 this.req.getData(this.cabinetListApi) .subscribe( res=>{ // 請(qǐng)求成功 this.cabinets = []; this.cabinets = res; },err=>{ // 請(qǐng)求失敗 this.cabinets = []; this.listErrMsg = err; }) } ngOnInit() { this.getList(); } }
頁(yè)面的顯示自己去完成吧!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。