之前 激动人心的 Angular HttpClient 这篇文章已经介绍过 HttpClient ,今天看到 angular-university 博客中介绍 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",response => {
                console.log("PATCH call in error",() => {
                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",response => {
                console.log("DELETE call in error",() => {
                console.log("The DELETE observable is Now completed.");
            });
}

发送 Post 请求

httpPostExample() {
    this.http.post("/courses/-KgVwECOnlc-LHb_B0cQ.json",{
            "courseListIcon": "...","description": "TEST","iconUrl": "..","url": "new-url"
        })
        .subscribe(
            (val) => {
                console.log("POST call successful value returned in body",response => {
                console.log("POST call in error",() => {
                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
    ],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 HTTP Client 快速入门的更多相关文章

  1. 通过AFNetworking 2.0上传iOS图像

    我一直在寻找新的AFNetworking2.0上传图像的例子.但是我正在撞墙,无法弄清楚代码有什么问题.所以这是我使用的代码TIA解决方法我最终使用了多部分请求

  2. ios – 在Objective-C中发送分块的HTTP 1.1请求

    我有以下问题:我正在创建一个非常大的SOAP请求(数据是一个编码为Base64字符串的视频),因此我不能将其作为原始SOAP请求发送,而是需要在HTTP1.1块中发送它.我似乎无法弄明白该怎么做.我在这里使用了代码:WhatarealternativestoNSURLConnectionforchunkedtransferencoding但它似乎没有做我认为应该做的事情–我可以看到请求作为单个请求

  3. ios – Swift2.0 HTTP请求无法正常工作

    参见英文答案>TransportsecurityhasblockedacleartextHTTP23个HelloStackoverflow,我将swift应用程序移动到Swift2.0后,我不断收到此错误:我看了下面的链接https://forums.developer.apple.com/thread/5835并将以下代码添加到我的info.plist中它仍然不起作用,任何人都有替代解决方案?解

  4. 如何在Swift语言中创建http请求

    概述:本文通过实例从同步和异步两种方式上回答了”如何在Swift语言中创建http请求“的问题。如果你对Objective-C比较了解的话,对于如何创建http请求你一定驾轻就熟了,而新语言Swift与其相比只有语法上的区别。但是,对才接触到这个崭新平台的初学者来说,他们仍然想知道“如何在Swift语言中创建http请求?”。在这里,我将作出一些建议来回答上述问题。常见的创建http请求的方式主要

  5. Swift HTTP请求集合

    )->Voidinprintln})带参数的get请求varrequest=HTTPTask()request.GET("http://google.com",parameters:["param":"param1","array":["firstarrayelement","second","third"],"num":23],arial;font-size:14px;line-height:21px">println("response:\(response.responSEObject!)")POS

  6. swift 自带HTTP请求

    )->Voidiniferror!=nil{println(error)}else{println(data)}}funcHTTPGet(url:String,callback:(String,String?)->Void){varrequest=NSMutableuRLRequest(URL:NSURL(string:url)!)HTTPsendRequest(request,callback)}funcHTTPsendRequest(request:NSMutableuRLRequest,callba

  7. Swift-网络请求http的基础学习

    swift发起网络请求自然有他自己的处理类NSURLRequest。这个跟android中httpClient的作用都是一样的。因此本篇博客只是记录一下这个过程,代码比较简单。这里封装了一个处理请求的httpController类。这个请求时异步处理的值得注意的是我写了一个delegate类来数据回调。viewcontroller顾名思义就是一个控制器,为了遵循MVC思想原则,我们不应该在控制器中写太多的逻辑代码,可以交给model层来出来,控制器负责调用就可以。这样代码更加易读。

  8. openstack swift和wsgi源码分析1 HTTP请求处理过程

    分析proxy-server代理服务的执行流程,其他的三个主要服务accountserver,containerserver,objectserver执行过程通proxyserver类似。入口函数调用run_wsgi,此函数完成以下工作:下面重点研究下process_request函数是如何把消息转化为HTTP的request对象这一过程。process_request函数,生成HttpProtocol对象,并执行init操作,注意,HttpProtocol对象自身没有init函数,所以会调用父类的父类的

  9. Swift: 用Alamofire做http请求,用ObjectMapper解析JSON

    ObjectMapper是一个双向的转化工具。最外面的一层是:所以对应的model定义是这样的:最重要的是先importObjectMapper。这样ObjectMapper就知道应该如何解析json字符串到对应的类对象中了。除了上面提到的,ObjectMapper还有很多其他的功能。最开始介绍使用Alamofire请求并成功返回之后,我们只是把字符串打印了出来。response.result.value取出了http请求之后返回的json串。不过Github奇葩的返回的结果就是一个JSONArray,居

  10. Swift 3中的HTTP请求

    asURL).你想用感叹号解开什么(!什么是变量名称?很多类名在Swift2和3之间发生了变化,因此您找到的答案可能不适用.以下示例连接到httpbin.org以获取您的IP地址:

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部