Angular9 向服務(wù)器發(fā)送數(shù)據(jù)

2020-07-06 14:54 更新

除了從服務(wù)器獲取數(shù)據(jù)外,HttpClient 還支持其它一些 HTTP 方法,比如 PUT,POSTDELETE,你可以用它們來(lái)修改遠(yuǎn)程數(shù)據(jù)。

本指南中的這個(gè)范例應(yīng)用包括一個(gè)簡(jiǎn)化版本的《英雄指南》,它會(huì)獲取英雄數(shù)據(jù),并允許用戶(hù)添加、刪除和修改它們。 下面幾節(jié)在 HeroesService 范例中展示了數(shù)據(jù)更新方法的一些例子。

發(fā)起一個(gè) POST 請(qǐng)求

應(yīng)用經(jīng)常在提交表單時(shí)通過(guò) POST 請(qǐng)求向服務(wù)器發(fā)送數(shù)據(jù)。 下面這個(gè)例子中,HeroesService 在向數(shù)據(jù)庫(kù)添加英雄時(shí)發(fā)起了一個(gè) HTTP POST 請(qǐng)求。

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() 一樣也有類(lèi)型參數(shù),可以用它來(lái)指出你期望服務(wù)器返回特定類(lèi)型的數(shù)據(jù)。該方法需要一個(gè)資源 URL 和兩個(gè)額外的參數(shù):

  • body - 要在請(qǐng)求體中 POST 過(guò)去的數(shù)據(jù)。

  • options - 一個(gè)包含方法選項(xiàng)的對(duì)象,在這里,它用來(lái)指定必要的請(qǐng)求頭。

該例子捕獲了前面所指的錯(cuò)誤。

HeroesComponent 通過(guò)訂閱該服務(wù)方法返回的 Observable 發(fā)起了一次實(shí)際的 POST 操作。

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

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

當(dāng)服務(wù)器成功做出響應(yīng)時(shí),會(huì)帶有這個(gè)新創(chuàng)建的英雄,然后該組件就會(huì)把這個(gè)英雄添加到正在顯示的 heroes 列表中。

發(fā)起 DELETE 請(qǐng)求

該應(yīng)用可以把英雄的 id 傳給 HttpClient.delete 方法的請(qǐng)求 URL 來(lái)刪除一個(gè)英雄。

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'))
    );
}

當(dāng) HeroesComponent 訂閱了該服務(wù)方法返回的 Observable 時(shí),就會(huì)發(fā)起一次實(shí)際的 DELETE 操作。

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

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

該組件不會(huì)等待刪除操作的結(jié)果,所以它的 subscribe (訂閱)中沒(méi)有回調(diào)函數(shù)。不過(guò)就算你不關(guān)心結(jié)果,也仍然要訂閱它。調(diào)用 subscribe() 方法會(huì)執(zhí)行這個(gè)可觀(guān)察對(duì)象,這時(shí)才會(huì)真的發(fā)起 DELETE 請(qǐng)求。

注:

  • 你必須調(diào)用 subscribe(),否則什么都不會(huì)發(fā)生。僅僅調(diào)用 HeroesService.deleteHero() 是不會(huì)發(fā)起 DELETE 請(qǐng)求的。

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

在調(diào)用方法返回的可觀(guān)察對(duì)象的 subscribe() 方法之前,HttpClient 方法不會(huì)發(fā)起 HTTP 請(qǐng)求。這適用于 HttpClient 的所有方法。

AsyncPipe 會(huì)自動(dòng)為你訂閱(以及取消訂閱)。

HttpClient 的所有方法返回的可觀(guān)察對(duì)象都設(shè)計(jì)為冷的。 HTTP 請(qǐng)求的執(zhí)行都是延期執(zhí)行的,讓你可以用 tapcatchError 這樣的操作符來(lái)在實(shí)際執(zhí)行 HTTP 請(qǐng)求之前,先對(duì)這個(gè)可觀(guān)察對(duì)象進(jìn)行擴(kuò)展。

調(diào)用 subscribe(...) 會(huì)觸發(fā)這個(gè)可觀(guān)察對(duì)象的執(zhí)行,并導(dǎo)致HttpClient` 組合并把 HTTP 請(qǐng)求發(fā)給服務(wù)器。

你可以把這些可觀(guān)察對(duì)象看做實(shí)際 HTTP 請(qǐng)求的藍(lán)圖。

實(shí)際上,每個(gè) subscribe() 都會(huì)初始化此可觀(guān)察對(duì)象的一次單獨(dú)的、獨(dú)立的執(zhí)行。 訂閱兩次就會(huì)導(dǎo)致發(fā)起兩個(gè) HTTP 請(qǐng)求。


<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>```

發(fā)起 PUT 請(qǐng)求

應(yīng)用可以使用 HttpClient 服務(wù)發(fā)送 PUT 請(qǐng)求。下面的 HeroesService 示例(就像 POST 示例一樣)用一個(gè)修改過(guò)的數(shù)據(jù)替換了該資源。

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))
    );
}

對(duì)于所有返回可觀(guān)察對(duì)象的 HTTP 方法,調(diào)用者(HeroesComponent.update())必須 subscribe()HttpClient.put() 返回的可觀(guān)察對(duì)象,才會(huì)真的發(fā)起請(qǐng)求。

添加和更新請(qǐng)求頭

很多服務(wù)器都需要額外的頭來(lái)執(zhí)行保存操作。 例如,服務(wù)器可能需要一個(gè)授權(quán)令牌,或者需要 Content-Type 頭來(lái)顯式聲明請(qǐng)求體的 MIME 類(lèi)型。

  1. 添加請(qǐng)求頭。

HeroesService 在一個(gè) httpOptions 對(duì)象中定義了這樣的頭,它們被傳遞給每個(gè) 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. 更新請(qǐng)求頭。

你不能直接修改前面的選項(xiàng)對(duì)象中的 HttpHeaders 請(qǐng)求頭,因?yàn)?HttpHeaders 類(lèi)的實(shí)例是不可變對(duì)象。請(qǐng)改用 set() 方法,以返回當(dāng)前實(shí)例應(yīng)用了新更改之后的副本。

下面的例子演示了當(dāng)舊令牌過(guò)期時(shí),可以在發(fā)起下一個(gè)請(qǐng)求之前更新授權(quán)頭。

    httpOptions.headers =
      httpOptions.headers.set('Authorization', 'my-new-auth-token');
以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)