Angular9 向服务器发送数据

2020-07-06 14:54 更新

除了从服务器获取数据外,HttpClient 还支持其它一些 HTTP 方法,比如 PUTPOSTDELETE,你可以用它们来修改远程数据。

本指南中的这个范例应用包括一个简化版本的《英雄指南》,它会获取英雄数据,并允许用户添加、删除和修改它们。 下面几节在 HeroesService 范例中展示了数据更新方法的一些例子。

发起一个 POST 请求

应用经常在提交表单时通过 POST 请求向服务器发送数据。 下面这个例子中,HeroesService 在向数据库添加英雄时发起了一个 HTTP POST 请求。

Path:"app/heroes/heroes.service.ts (addHero)" 。

/** POST: add a new hero to the database */
addHero (hero: Hero): Observable<Hero> {
  return this.http.post<Hero>(this.heroesUrl, hero, httpOptions)
    .pipe(
      catchError(this.handleError('addHero', hero))
    );
}

HttpClient.post() 方法像 get() 一样也有类型参数,可以用它来指出你期望服务器返回特定类型的数据。该方法需要一个资源 URL 和两个额外的参数:

  • body - 要在请求体中 POST 过去的数据。

  • options - 一个包含方法选项的对象,在这里,它用来指定必要的请求头。

该例子捕获了前面所指的错误。

HeroesComponent 通过订阅该服务方法返回的 Observable 发起了一次实际的 POST 操作。

Path:"app/heroes/heroes.component.ts (addHero)" 。

this.heroesService
  .addHero(newHero)
  .subscribe(hero => this.heroes.push(hero));

当服务器成功做出响应时,会带有这个新创建的英雄,然后该组件就会把这个英雄添加到正在显示的 heroes 列表中。

发起 DELETE 请求

该应用可以把英雄的 id 传给 HttpClient.delete 方法的请求 URL 来删除一个英雄。

Path:"app/heroes/heroes.service.ts (deleteHero)" 。

/** DELETE: delete the hero from the server */
deleteHero (id: number): Observable<{}> {
  const url = `${this.heroesUrl}/${id}`; // DELETE api/heroes/42
  return this.http.delete(url, httpOptions)
    .pipe(
      catchError(this.handleError('deleteHero'))
    );
}

HeroesComponent 订阅了该服务方法返回的 Observable 时,就会发起一次实际的 DELETE 操作。

Path:"app/heroes/heroes.component.ts (deleteHero)" 。

this.heroesService
  .deleteHero(hero.id)
  .subscribe();

该组件不会等待删除操作的结果,所以它的 subscribe (订阅)中没有回调函数。不过就算你不关心结果,也仍然要订阅它。调用 subscribe() 方法会执行这个可观察对象,这时才会真的发起 DELETE 请求。

注:

  • 你必须调用 subscribe(),否则什么都不会发生。仅仅调用 HeroesService.deleteHero() 是不会发起 DELETE 请求的。

// oops ... subscribe() is missing so nothing happens
    this.heroesService.deleteHero(hero.id);

在调用方法返回的可观察对象的 subscribe() 方法之前,HttpClient 方法不会发起 HTTP 请求。这适用于 HttpClient 的所有方法。

AsyncPipe 会自动为你订阅(以及取消订阅)。

HttpClient 的所有方法返回的可观察对象都设计为冷的。 HTTP 请求的执行都是延期执行的,让你可以用 tapcatchError 这样的操作符来在实际执行 HTTP 请求之前,先对这个可观察对象进行扩展。

调用 subscribe(...) 会触发这个可观察对象的执行,并导致HttpClient` 组合并把 HTTP 请求发给服务器。

你可以把这些可观察对象看做实际 HTTP 请求的蓝图。

实际上,每个 subscribe() 都会初始化此可观察对象的一次单独的、独立的执行。 订阅两次就会导致发起两个 HTTP 请求。


<br>const req = http.get<Heroes&('/api/heroes');
<br>// 0 requests made - .subscribe() not called.
<br>req.subscribe();
<br>// 1 request made.
<br>req.subscribe();
<br>// 2 requests made.
<br>```

发起 PUT 请求

应用可以使用 HttpClient 服务发送 PUT 请求。下面的 HeroesService 示例(就像 POST 示例一样)用一个修改过的数据替换了该资源。

Path:"app/heroes/heroes.service.ts (updateHero)" 。

/** PUT: update the hero on the server. Returns the updated hero upon success. */
updateHero (hero: Hero): Observable<Hero> {
  return this.http.put<Hero>(this.heroesUrl, hero, httpOptions)
    .pipe(
      catchError(this.handleError('updateHero', hero))
    );
}

对于所有返回可观察对象的 HTTP 方法,调用者(HeroesComponent.update())必须 subscribe()HttpClient.put() 返回的可观察对象,才会真的发起请求。

添加和更新请求头

很多服务器都需要额外的头来执行保存操作。 例如,服务器可能需要一个授权令牌,或者需要 Content-Type 头来显式声明请求体的 MIME 类型。

  1. 添加请求头。

HeroesService 在一个 httpOptions 对象中定义了这样的头,它们被传递给每个 HttpClient 的保存型方法。

Path:"app/heroes/heroes.service.ts (httpOptions)" 。

    import { HttpHeaders } from '@angular/common/http';


    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type':  'application/json',
        'Authorization': 'my-auth-token'
      })
    };

  1. 更新请求头。

你不能直接修改前面的选项对象中的 HttpHeaders 请求头,因为 HttpHeaders 类的实例是不可变对象。请改用 set() 方法,以返回当前实例应用了新更改之后的副本。

下面的例子演示了当旧令牌过期时,可以在发起下一个请求之前更新授权头。

    httpOptions.headers =
      httpOptions.headers.set('Authorization', 'my-new-auth-token');
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号