Angular学习笔记—HttpClient (转载)
HttpClientModule 应用
导入新的 HTTP Module
import {HttpClientModule} from '@angular/common/http';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
需要注意的是,现在 JSON 是默认的数据格式,我们不需要再进行显式的解析。即我们不需要再使用以下代码:
http.get(url).map(res => res.json()).subscribe(...)
现在我们可以这样写:
http.get(url).subscribe(...)
发送 Get 请求
import {Component, OnInit} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {HttpClient} from "@angular/common/http";
import * as _ from 'lodash';
interface Course {
description: string;
courseListIcon:string;
iconUrl:string;
longDescription:string;
url:string;
}
@Component({
selector: 'app-root',
template: `
<ul *ngIf="courses$ | async as courses else noData">
<li *ngFor="let course of courses">
{{course.description}}
</li>
</ul>
<ng-template #noData>No Data Available</ng-template>
`})
export class AppComponent implements OnInit {
courses$: Observable<any>;
constructor(private http:HttpClient) {}
ngOnInit() {
this.courses$ = this.http
.get("https://angular-http-guide.firebaseio.com/courses.json")
.map(data => _.values(data))
.do(console.log);
}
}
设置查询参数
假设发送 Get 请求时,需要设置对应的查询参数,预期的 URL 地址如下:
https://angular-http-guide.firebaseio.com/courses.json?orderBy="$key"&limitToFirst=1
创建 HttpParams 对象
import {HttpParams} from "@angular/common/http";
const params = new HttpParams()
.set('orderBy', '"$key"')
.set('limitToFirst', "1");
this.courses$ = this.http
.get("/courses.json", {params})
.do(console.log)
.map(data => _.values(data))
需要注意的是,我们通过链式语法调用 set() 方法,构建 HttpParams 对象。这是因为 HttpParams 对象是不可变的,通过 set() 方法可以防止该对象被修改。
每当调用 set() 方法,将会返回包含新值的 HttpParams 对象,因此如果使用下面的方式,将不能正确的设置参数。
const params = new HttpParams();
params.set('orderBy', '"$key"')
params.set('limitToFirst', "1");
使用 fromString 语法
const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'});
使用 request() API
const params = new HttpParams({fromString: 'orderBy="$key"&limitToFirst=1'});
this.courses$ = this.http
.request(
"GET",
"/courses.json",
{
responseType:"json",
params
})
.do(console.log)
.map(data => _.values(data));
设置 HTTP Headers
const headers = new HttpHeaders().set("X-CustomHeader", "custom header value");
this.courses$ = this.http
.get(
"/courses.json",
{headers})
.do(console.log)
.map(data => _.values(data));
发送 Put 请求
httpPutExample() {
const headers = new HttpHeaders().set("Content-Type", "application/json");
this.http.put("/courses/-KgVwECOnlc-LHb_B0cQ.json",
{
"courseListIcon": ".../main-page-logo-small-hat.png",
"description": "Angular Tutorial For Beginners TEST",
"iconUrl": ".../angular2-for-beginners.jpg",
"longDescription": "...",
"url": "new-value-for-url"
},
{headers})
.subscribe(
val => {
console.log("PUT call successful value returned in body",
val);
},
response => {
console.log("PUT call in error", response);
},
() => {
console.log("The PUT observable is now completed.");
}
);
}
发送 Patch 请求
httpPatchExample() {
this.http.patch("/courses/-KgVwECOnlc-LHb_B0cQ.json",
{
"description": "Angular Tutorial For Beginners PATCH TEST",
})
.subscribe(
(val) => {
console.log("PATCH call successful value returned in body",
val);
},
response => {
console.log("PATCH call in error", response);
},
() => {
console.log("The PATCH observable is now completed.");
});
}
发送 Delete 请求
httpDeleteExample() {
this.http.delete("/courses/-KgVwECOnlc-LHb_B0cQ.json")
.subscribe(
(val) => {
console.log("DELETE call successful value returned in body",
val);
},
response => {
console.log("DELETE call in error", response);
},
() => {
console.log("The DELETE observable is now completed.");
});
}
发送 Post 请求
httpPostExample() {
this.http.post("/courses/-KgVwECOnlc-LHb_B0cQ.json",
{
"courseListIcon": "...",
"description": "TEST",
"iconUrl": "..",
"longDescription": "...",
"url": "new-url"
})
.subscribe(
(val) => {
console.log("POST call successful value returned in body",
val);
},
response => {
console.log("POST call in error", response);
},
() => {
console.log("The POST observable is now completed.");
});
}
避免重复请求
duplicateRequestsExample() {
const httpGet$ = this.http
.get("/courses.json")
.map(data => _.values(data));
httpGet$.subscribe(
(val) => console.log("logging GET value", val)
);
this.courses$ = httpGet$;
}
在上面例子中,我们正在创建了一个 HTTP observable 对象 httpGet$,接着我们直接订阅该对象。然后,我们把 httpGet$ 对象赋值给 courses$ 成员变量,最后在模板中使用 async 管道订阅该对象。
这将导致发送两个 HTTP 请求,在这种情况下,请求显然是重复的,因为我们只希望从后端查询一次数据。为了避免发送冗余的请求,我们可以使用 RxJS 提供的 shareReplay 操作符:
// put this next to the other RxJs operator imports
import 'rxjs/add/operator/shareReplay'; const httpGet$ = this.http
.get("/courses.json")
.map(data => _.values(data))
.shareReplay();
并行发送多个请求
并行发送 HTTP 请求的一种方法是使用 RxJs 中的 forkjoin 操作符:
import 'rxjs/add/observable/forkJoin';
parallelRequests() {
const parallel$ = Observable.forkJoin(
this.http.get('/courses/-KgVwEBq5wbFnjj7O8Fp.json'),
this.http.get('/courses/-KgVwECOnlc-LHb_B0cQ.json')
);
parallel$.subscribe(
values => {
console.log("all values", values)
}
);
}
顺序发送 Http 请求
sequentialRequests() {
const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json')
.switchMap(course => {
course.description+= ' - TEST ';
return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course)
});
sequence$.subscribe();
}
获取顺序发送 Http 请求的结果
sequentialRequests() {
const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json')
.switchMap(course => {
course.description+= ' - TEST ';
return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course)
},
(firstHTTPResult, secondHTTPResult) => [firstHTTPResult, secondHTTPResult]);
sequence$.subscribe(values => console.log("result observable ", values) );
}
请求异常处理
throwError() {
this.http
.get("/api/simulate-error")
.catch( error => {
// here we can show an error message to the user,
// for example via a service
console.error("error catched", error);
return Observable.of({description: "Error Value Emitted"});
})
.subscribe(
val => console.log('Value emitted successfully', val),
error => {
console.error("This line is never called ",error);
},
() => console.log("HTTP Observable completed...")
);
}
当发生异常时,控制台的输出结果:
Error catched
HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/api/simulate-error", ok: false, … }
Value emitted successfully {description: "Error Value Emitted"}
HTTP Observable completed...
Http 拦截器
定义拦截器
import {Injectable} from "@angular/core";
import {HttpEvent, HttpHandler, HttpInterceptor} from "@angular/common/http";
import {HttpRequest} from "@angular/common/http";
import {Observable} from "rxjs/Observable";
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const clonedRequest = req.clone({
headers: req.headers.set('X-CustomAuthHeader', authService.getToken())
});
console.log("new headers", clonedRequest.headers.keys());
return next.handle(clonedRequest);
}
}
配置拦截器
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
[ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ]
],
bootstrap: [AppComponent]
})
export class AppModule { }
Http 进度事件
longRequest() {
const request = new HttpRequest(
"POST", "/api/test-request", {},
{reportProgress: true});
this.http.request(request)
.subscribe(
event => {
if (event.type === HttpEventType.DownloadProgress) {
console.log("Download progress event", event);
}
if (event.type === HttpEventType.UploadProgress) {
console.log("Upload progress event", event);
}
if (event.type === HttpEventType.Response) {
console.log("response received...", event.body);
}
}
);
}
上面示例运行后,控制台的可能的输出结果:
Upload progress event Object {type: 1, loaded: 2, total: 2}
Download progress event Object {type: 3, loaded: 31, total: 31}
Response Received... Object {description: "POST Response"}
转载自:
Angular学习笔记—HttpClient (转载)的更多相关文章
- angular学习笔记(三十一)-$location(2)
之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...
- angular学习笔记(三十一)-$location(1)
本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...
- angular学习笔记(三十)-指令(10)-require和controller
本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...
- angular学习笔记(三十)-指令(7)-compile和link(2)
继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...
- angular学习笔记(三十)-指令(7)-compile和link(1)
这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...
- angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令
在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...
- angular学习笔记(三十)-指令(5)-link
这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...
- angular学习笔记(三十)-指令(2)-restrice,replace,template
本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...
- angular学习笔记(三十)-指令(1)-概述
之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('dir ...
随机推荐
- [转]c++ virtual public的含义和作用
我在写基于MICO的CORBA程序的时候遇到的,上网查了一下 转自:http://bbs.seu.edu.cn/pc/pccon.php?id=872&nid=16822 Question:父 ...
- 脚本 sh 和 ./ 的区别,exec和source
如果.不在PATH里面,要执行当前目录下的可执行文件,使用全路径: ./executable-file PATH是环境变量,如果将当前目录“./”添加到环境变量中,那么也可以不用“./”,直接输入当前 ...
- ASP.NET MVC 4新建库项目中找不到 System.Web.Security 的引用
.NET 4中,WebSecurity的引用已经不再System.Web中,而是转移到了System.Web.ApplicationServices Dll中,添加该Dll即可.
- 详解C#中通过委托来实现回调函数功能的方法
委托:类型安全的指向函数的指针 使用步骤 1:声明一个委托 delegate string DelString(string s) 2:定义一个委托变量 DelString del = new Del ...
- C++基础细节2
1.关于引用和指针 概念上,引用(&)并不是对象,而是一个已经存在的对象的别名:引用不可以重新绑定到另外一个对象,因此引用必须初始化.(类比const,一经定义就不能修改,所以必须初始化,是同 ...
- Java泛型小结
本来想着写一篇总结Java泛型的文章,但是却发现了一篇不错的博文,引用自: http://www.cnblogs.com/lwbqqyumidi/p/3837629.html#undefined 现摘 ...
- PHP实现懒加载
寻常php的加载是通过include(),require()等方法来加载外部文件,之后再通过实例调用方法或直接调用静态方法,而这样子写引入语句实在很麻烦,有的框架会将特定路径的文件全部引入,直接实例化 ...
- (转)java 静态内部类
转自:http://blog.sina.com.cn/s/blog_605f5b4f0100zbps.html 参考:http://docs.oracle.com/javase/tutorial/ja ...
- WPF DataGrid 获取选中的当前行某列值
方法一: DataRowView mySelectedElement = (DataRowView)dataGrid1.SelectedItem; ]ToString(); 方法二: var a = ...
- acdream1415(dij+优先队列+桥)
这题好坑,卡SPFA... 无奈只能用dij+优先队列了. 因为好久没有写过代码了,所以今天写dij时候突然觉得复杂度不对,dij+优先队列的复杂度是(n+m)logn,这种复杂度对于稠密图是非常慢! ...