HTTP服务 HttpClientModule

模拟数据服务器 In-memory Web API

这个内存 Web API 在拦截这些请求、操作一个内存数据库,并且给出仿真的响应。

重要: 这个内存 Web API 模块与 Angular 中的 HTTP 模块无关。
当你的真实服务器就绪时,请移除这个内存 Web API,应用的请求就会直接发给服务器。

英雄与 HTTP

HttpClient.get

HttpClient.get 默认情况下把响应体当做无类型的 JSON 对象进行返回。 如果指定了可选的模板类型 ,就会给返回你一个类型化的对象。

错误处理

.pipe() 方法来扩展 Observable 的结果

  1. getHeroes (): Observable<Hero[]> {
  2. return this.http.get<Hero[]>(this.heroesUrl)
  3. .pipe(
  4. catchError(this.handleError<Hero[]>('getHeroes', []))
  5. );
  6. }

handleError错误处理器

  • 利用泛型决定错误返回类型
  • 反馈用户+返回一个安全值

    1. private handleError<T> (operation = 'operation', result?: T) {
    2. return (error: any): Observable<T> => {
    3. // 控制台打印
    4. console.error(error); // log to console instead
    5. // 汇报一个用户友好的信息
    6. this.log(`${operation} failed: ${error.message}`);
    7. // 返回一个安全值
    8. return of(result as T);
    9. };
    10. }

窥探Observable (tap into the Observable)

该操作符会查看 Observable 中的值,使用那些值做一些事情,并且把它们传出来

  1. tap(_ => this.log('fetched heroes'))

httpOptions

put, post, delete都需要

  1. const httpOptions = {
  2. headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  3. };

通过 id 获取英雄 get

大多数的 Web API 都支持以 :baseURL/:id 的形式根据 id 进行获取。
put 方法,英雄 Web API 通过英雄对象的 id 就可以知道要修改哪个英雄

  1. return this.http.put(this.heroesUrl, hero, httpOptions).pipe();

修改英雄 put

英雄 Web API 通过英雄对象的 id 就可以知道要修改哪个英雄

  1. return this.http.put(this.heroesUrl, hero, httpOptions)

添加英雄 post

可以使用一个和添加按钮成对的 input 元素, 不需要双向绑定

  1. addHero (hero: Hero): Observable<Hero> {}

删除英雄 delete

  1. // 组件与 heroService.delete() 返回的 Observable 还完全没有关联。必须订阅它。
  2. delete(hero: Hero): void {
  3. this.heroes = this.heroes.filter(h => h !== hero);
  4. this.heroService.deleteHero(hero).subscribe();
  5. }

搜索英雄

AsyncPipe

  • $ 是一个命名惯例,用来表明 heroes$ 是一个 Observable,而不是数组。
  • [AsyncPipe](https://angular.cn/api/common/AsyncPipe) 会自动订阅到 Observable,这样你就不用再在组件类中订阅了

    1. <li *ngFor="let hero of heroes$ | async" >

    RxJS Subject 类型的 searchTerms

  • Subject 既是可观察对象的数据源,本身也是 Observable。

  • 你可以像订阅任何 Observable 一样订阅 Subject。
  • 你还可以通过调用它的 next(value) 方法往 Observable 中推送一些值,就像 search() 方法中一样。

searchTerms 是一个可观察对象

  1. // Push a search term into the observable stream.
  2. search(term: string): void {
  3. this.searchTerms.next(term);
  4. }

串联 RxJS 操作符

如果每当用户击键后就直接调用 searchHeroes() 将导致创建海量的 HTTP 请求,浪费服务器资源并消耗大量网络流量,应该怎么做呢?
见文档

模块

InMemoryDbService

  1. import { InMemoryDbService } from 'angular-in-memory-web-api';

HttpClientModule

  1. import { HttpClientModule } from '@angular/common/http';

HttpClientInMemoryWebApiModule

  1. import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';

HttpClient

HttpHeaders

  1. import { HttpClient, HttpHeaders } from '@angular/common/http';