Angular 4+ HttpClient
個(gè)人博客遷移至 http://www.sulishibaobei.com? 處;
這篇,算是上一篇Angular 4+ Http的后續(xù);
Angular 4.3.0-rc.0 版本已經(jīng)發(fā)布?。在這個(gè)版本中,我們等到了一個(gè)令人興奮的新功能 - HTTPClient API 的改進(jìn)版本;
HttpClient 是已有 Angular HTTP API 的演進(jìn),它在一個(gè)單獨(dú)的 @angular/common/http 包中。這是為了確保現(xiàn)有的代碼庫(kù)可以緩慢遷移到新的 API;
大多數(shù)前端應(yīng)用都需要通過(guò) HTTP 協(xié)議與后端服務(wù)器通訊。現(xiàn)代瀏覽器支持使用兩種不同的 API 發(fā)起 HTTP 請(qǐng)求:XMLHttpRequest 接口和 fetch() API;
@angular/common/http中的HttpClient類,Angular 為應(yīng)用程序提供了一個(gè)簡(jiǎn)化的 API 來(lái)實(shí)現(xiàn) HTTP 功能。它基于瀏覽器提供的XMLHttpRequest接口。 HttpClient帶來(lái)的其它優(yōu)點(diǎn)包括:可測(cè)試性、強(qiáng)類型的請(qǐng)求和響應(yīng)對(duì)象、發(fā)起請(qǐng)求與接收響應(yīng)時(shí)的攔截器支持,以及更好的、基于可觀察(Observable)對(duì)象的錯(cuò)誤處理機(jī)制;
1.如何使用httpClient;
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpClientModule} from '@angular/common/http';
@NgModule({imports: [BrowserModule,// Include it under 'imports' in your application module// after BrowserModule.HttpClientModule,],
})
export class MyAppModule {} 注意:導(dǎo)入方式和HttpModule一樣的,記得要在BrowserModule后面導(dǎo)入;區(qū)別是:在@angular/common/http 模塊里面,而不是@angular/http中
這樣我們可以使用這些啦:
class HttpClient {request(first: string|HttpRequest<any>, url?: string, options: {...}): Observable<any>delete(url: string, options: {...}): Observable<any>get(url: string, options: {...}): Observable<any>head(url: string, options: {...}): Observable<any>jsonp<T>(url: string, callbackParam: string): Observable<T>options(url: string, options: {...}): Observable<any>patch(url: string, body: any|null, options: {...}): Observable<any>post(url: string, body: any|null, options: {...}): Observable<any>put(url: string, body: any|null, options: {...}): Observable<any> }
2.發(fā)起一個(gè)請(qǐng)求來(lái)獲取Json數(shù)據(jù);
?? 首先創(chuàng)建一個(gè)json文件,其實(shí)就是上一篇的同一個(gè)json文件:
{"data": [{ "id": 1, "name": "Windstorm" },{ "id": 2, "name": "Bombasto" },{ "id": 3, "name": "Magneta" },{ "id": 4, "name": "Tornado" }]
} 怎么調(diào)用Http請(qǐng)求呢?
?? 2.1 app.componment.ts;
import { Component,OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http'; /*注釋1*/
@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private http:HttpClient){} datas:string[];ngOnInit(){this.http.get('./assets/heroes.json').subscribe(data=>{ /*注釋2*/this.datas=data['data'];console.log(this.datas)}) }
} 注意:
? 注釋1: 組件中引入的是HttpClient,也是在單獨(dú)的庫(kù),@angular/common/http中;
?????????????? 之前的項(xiàng)目里面引入的一直都是http,這就是改版后的區(qū)別;
? 注釋2:現(xiàn)在 JSON 是默認(rèn)的數(shù)據(jù)格式,我們不需要再進(jìn)行顯式的解析;this.http.get('xx').subscribe();
????????????? 之前的還需要res.json()去手動(dòng)轉(zhuǎn);
?還有一點(diǎn)要注意:我并沒(méi)有去hero.service.ts里面去操作了,而是直接在組件中發(fā)請(qǐng)求獲取數(shù)據(jù),這樣更加簡(jiǎn)單明了;
<div><ul *ngFor="let data of datas"><li>{{data.id}} {{data.name}}</li></ul> </div>
html代碼還是一樣簡(jiǎn)單,并沒(méi)有改變;
這是相比較之前的Http簡(jiǎn)單的方式;
get(url: string, options: {headers?: HttpHeaders,observe?: HttpObserve,params?: HttpParams,reportProgress?: boolean,responseType?: 'arraybuffer'|'blob'|'json'|'text',withCredentials?: boolean,}): Observable<any>
這是get方法詳解,請(qǐng)注意,返回的都是observable對(duì)象,而不是使用promise了;
3.響應(yīng)體的檢查
?? 3.1上面的代碼中:
datas:string[]; //定義一個(gè)接口來(lái)描述這個(gè)類型的正確形態(tài)this.datas=data['data']; /*注釋1*/ ?注釋1:
?? 我們?nèi)son對(duì)象data值時(shí)要data['data'],而不是之前的data.data了;如果改成:
this.datas=data.data;
會(huì)報(bào)錯(cuò):
does not exist on type 'Object
那是因?yàn)?code>HttpClient把 JSON 格式的響應(yīng)體解析成了一個(gè)Object,它并不知道這個(gè)對(duì)象的形態(tài)應(yīng)該是什么。所以我們應(yīng)該告訴你需要取得data是個(gè)什么類型;這也是更符合typescript語(yǔ)法的做法;
4. 如果將要獲取的不是JSON文件如何?
this.http.get('/assets/1.txt',{responseType:'text'}).subscribe(data=>console.log(data)
) 注意:這樣我們就要指定需要獲取的文本格式;
? 控制臺(tái)將會(huì)打印我的1.txt中的內(nèi)容:www.sulishibaobei.com
?5.如何帶參查詢數(shù)據(jù)
const params = new HttpParams().set('id', '1').set('name','Windstorm')this.cus=this.http.get('assets/heroes.json',{params}).do(console.log).map(data=>console.log( _.values(data))
); 引入:httpParams參數(shù):
import {HttpClient, HttpParams} from '@angular/common/http'; 我們通過(guò)鏈?zhǔn)秸Z(yǔ)法調(diào)用set()方法,構(gòu)建了params對(duì)象;每當(dāng)set()方法被調(diào)用時(shí),都會(huì)包含新的值進(jìn)來(lái),并且防止之前對(duì)象不被修改;
http://localhost:4200/assets/heroes.json?id=1&name=Windstorm 請(qǐng)求的鏈接地址將會(huì)是這樣的形式;這個(gè)有點(diǎn)像http里添加url參數(shù);
還可以設(shè)置Headers;
const headers = new HttpHeaders().set("X-CustomHeader", "custom header value"); 還有其他的請(qǐng)求,之后會(huì)逐一分析;
另外還有幾點(diǎn)比較重要的:
? 多行并發(fā)發(fā)送請(qǐng)求和順序發(fā)送請(qǐng)求,避免發(fā)送重復(fù)請(qǐng)求;
避免發(fā)送重復(fù)請(qǐng)求import 'rxjs/add/operator/shareReplay';const httpGet = this.http.get("assets/heroes.json").map(data => _.values(data)).shareReplay();這樣即使你將 httpGet再賦值給另一個(gè)變量,或重復(fù)調(diào)用也不會(huì)再次請(qǐng)求了 并行發(fā)送 HTTP 請(qǐng)求的一種方法是使用 RxJs 中的 forkjoin 操作符:import 'rxjs/add/observable/forkJoin';
Requests() {const result = Observable.forkJoin(this.http.get('/assets/heroes.json'),this.http.get('/assets/heroes.json'));result.subscribe(values => {console.log("all values", values)});
} 順序發(fā)送請(qǐng)求 sequentialRequests() {const sequence$ = this.http.get<Hero>('/assets/heroes.json').switchMap(hero => {hero.id+= ' - TEST ';return this.http.put('/assets/heroes.json', hero)});sequence$.subscribe(); }
6. 攔截器? (攔截所有的請(qǐng)求和響應(yīng)這也是@angular/common/http的核心特性之一)
??? 它能聲明一些攔截器,攔在應(yīng)用和后端之間。當(dāng)應(yīng)用程序發(fā)起一個(gè)請(qǐng)求時(shí),攔截器可以在請(qǐng)求被發(fā)往服務(wù)器之前先轉(zhuǎn)換這個(gè)請(qǐng)求。并且在應(yīng)用看到服務(wù)器發(fā)回來(lái)的響應(yīng)之前,轉(zhuǎn)換這個(gè)響應(yīng)。這對(duì)于處理包括認(rèn)證和記錄日志在內(nèi)的一系列工作都非常有用。
? 6.1 如何寫一個(gè)攔截器
import {Injectable} from '@angular/core'; import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse} from '@angular/common/http'; import {Observable} from 'Rxjs/Observable';@Injectable() export class NoopInterceptor implements HttpInterceptor {intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {return next.handle(req).map(event => {if (event instanceof HttpResponse) {if (event.status === 401) {// JWT expired, go to login}}return event;}} }
1.intercept是一個(gè)方法,它把一個(gè)請(qǐng)求對(duì)象轉(zhuǎn)換成一個(gè)返回這個(gè)響應(yīng)的可觀察對(duì)象(Observable)。從這個(gè)意義上說(shuō),每個(gè)攔截器都要完全自己處理這個(gè)請(qǐng)求;
2.響應(yīng)攔截器可以通過(guò)在 next.handle(req) 返回的流對(duì)象 (即 Observable 對(duì)象) 上應(yīng)用附加的 Rx 操作符來(lái)轉(zhuǎn)換響應(yīng)事件流對(duì)象;
內(nèi)部可以做自己的處理操作;
但是此時(shí)攔截器還未使用在組件上;
?
import {NgModule} from '@angular/core';
import {HTTP_INTERCEPTORS} from '@angular/common/http';@NgModule({providers: [{provide: HTTP_INTERCEPTORS,useClass: NoopInterceptor,multi: true,}],
})
export class AppModule {} ?
providers里面配置我們的信息;
注意multi: true選項(xiàng)。這是必須的,因?yàn)樗鼤?huì)告訴 Angular 這個(gè) HTTP_INTERCEPTORS 表示的是一個(gè)數(shù)組,而不是單個(gè)的值;
?
?
?
?
?
?
?
?
?
?
?
?????
???
轉(zhuǎn)載于:https://www.cnblogs.com/sulishibaobei/p/7455666.html
總結(jié)
以上是生活随笔為你收集整理的Angular 4+ HttpClient的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 检查疱疹需要多少费用
- 下一篇: 培训月嫂多少钱啊?