詳解封裝基礎(chǔ)的angular4的request請(qǐng)求方法
為什么要封裝呢?
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" : "用戶(hù)名或密碼錯(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)求完成后返回的值類(lèi)型是any
**/
public getData(url, time = this.setTimeout):Observable<any> {
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 里一樣,是可以直接用的字符串類(lèi)型的錯(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)求完成后返回的值類(lèi)型是any
**/
public getData(url, time = this.setTimeout):Observable<any> {
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)求完成后返回的值類(lèi)型是any
**/
public getData(url, time = this.setTimeout):Observable<any> {
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è)滿(mǎn)足基本需求的,可以公共使用的請(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<any>; // 列表數(shù)據(jù)(類(lèi)型為數(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í)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
用Angular實(shí)現(xiàn)一個(gè)掃雷的游戲示例
這篇文章主要介紹了用Angular實(shí)現(xiàn)一個(gè)掃雷的游戲示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Javascript基礎(chǔ)_標(biāo)記文字的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇Javascript基礎(chǔ)_標(biāo)記文字的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06
探討AngularJs中ui.route的簡(jiǎn)單應(yīng)用
這篇文章主要介紹了AngularJs中ui.route的簡(jiǎn)單應(yīng)用,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
解決Angular2 router.navigate刷新頁(yè)面的問(wèn)題
今天小編就為大家分享一篇解決Angular2 router.navigate刷新頁(yè)面的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
分享使用AngularJS創(chuàng)建應(yīng)用的5個(gè)框架
如果你計(jì)劃使用AngularJS創(chuàng)建你的Web應(yīng)用,那現(xiàn)在就開(kāi)始吧。你不需要有任何的恐懼和擔(dān)心,因?yàn)楝F(xiàn)在有很多的框架都可以很好地支持AngularJS2015-12-12
解決angular雙向綁定無(wú)效果,ng-model不能正常顯示的問(wèn)題
今天小編就為大家分享一篇解決angular雙向綁定無(wú)效果,ng-model不能正常顯示的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10

