web-dev-qa-db-ja.com

Angular 2 http.get()、map()、subscribe()、および観測パターン - 基本的な理解

今、私は私が3つのリンクを持っている最初のページを持っています。最後の「友達」リンクをクリックすると、適切な友達コンポーネントが起動されます。そこに、私はfriends.jsonファイルに格納されている私の友人のリストを取得/取得したいです。今まではすべてうまくいきました。しかし、私はまだRxJのオブザーバブル、マップ、サブスクライブの概念を使ったangular2のHTTPサービスの初心者です。私はそれを理解し、いくつかの記事を読もうとしましたが、実際の作業に入るまでは、これらの概念を正しく理解するつもりはありません。

ここで私はすでにHTTP関連の仕事以外の仕事をしているplnkrを作りました。

プランクル

myfriends.ts

 import {Component,View,CORE_DIRECTIVES} from 'angular2/core';
 import {Http, Response,HTTP_PROVIDERS} from 'angular2/http';
 import 'rxjs/Rx';
 @Component({
    template: `
    <h1>My Friends</h1>
    <ul>
      <li *ngFor="#frnd of result">
          {{frnd.name}} is {{frnd.age}} years old.
      </li>
    </ul>
    `,
    directive:[CORE_DIRECTIVES]
  })

  export class FriendsList{

      result:Array<Object>; 
      constructor(http: Http) { 
        console.log("Friends are being called");

       // below code is new for me. So please show me correct way how to do it and please explain about .map and .subscribe functions and observable pattern.

        this.result = http.get('friends.json')
                      .map(response => response.json())
                      .subscribe(result => this.result =result.json());

        //Note : I want to fetch data into result object and display it through ngFor.

       }
  }

正しく案内して説明してください。私はそれが多くの新しい開発者にとってとても有益になることを知っています。

162
nyks

これはあなたが間違ったところです:

this.result = http.get('friends.json')
                  .map(response => response.json())
                  .subscribe(result => this.result =result.json());

そのはず:

http.get('friends.json')
                  .map(response => response.json())
                  .subscribe(result => this.result =result);

または

http.get('friends.json')
                  .subscribe(result => this.result =result.json());

あなたは2つの間違いを犯しました:

1 - 観測可能なもの自体をthis.resultに割り当てました。あなたが実際に友達のリストをthis.resultに割り当てたいとき。正しい方法は次のとおりです。

  • あなたは観測量を購読します。 .subscribeは、実際にオブザーバブルを実行する関数です。以下のように3つのコールバックパラメータを取ります。

    .subscribe(success, failure, complete);

例えば:

.subscribe(
    function(response) { console.log("Success Response" + response)},
    function(error) { console.log("Error happened" + error)},
    function() { console.log("the subscription is completed")}
);

通常、成功コールバックの結果を受け取り、それを変数に代入します。エラーコールバックは一目瞭然です。完全なコールバックは、エラーなしで最後の結果を受け取ったことを判断するために使用されます。 あなたの略奪者では、完全なコールバックは常に成功またはエラーコールバックの後に呼ばれるでしょう。

2番目の間違い、あなたは.json()上で.map(res => res.json())を呼び出し、それからオブザーバブルの成功コールバックでそれを再度呼び出しました。 .map()は、成功コールバックに渡される前にあなたが返すもの(あなたの場合は.json())に結果を変換するトランスフォーマーです。

198
Abdulrahman

概念

オブザーバブルは、簡単に言えば、非同期の処理とイベントに取り組みます。約束と比較すると、これはobservables = promises + eventsとして記述できます。

オブザーバブルに最適なのは、それらが怠惰であること、それらをキャンセルすることができ、あなたがそれらの中にいくつかの演算子を適用できることです(map、...のように)。これは非常に柔軟な方法で非同期のことを扱うことを可能にします。

オブザーバブルの最高の能力を説明する優れたサンプルは、フィルタ入力を対応するフィルタ処理済みリストに接続する方法です。ユーザーが文字を入力すると、リストは更新されます。 Observablesは対応するAJAX要求を処理し、入力内の新しい値によって別の要求がトリガーされた場合は、前の進行中の要求を取り消します。これは対応するコードです:

this.textValue.valueChanges
    .debounceTime(500)
    .switchMap(data => this.httpService.getListValues(data))
    .subscribe(data => console.log('new list values', data));

textValueはフィルター入力に関連したコントロールです)。

このようなユースケースのより広い記述はここにあります: どのようにAngular 2のフォーム変更を監視するには?

AngularConnect 2015とEggHeadには、2つの素晴らしいプレゼンテーションがあります。

Christoph Burgdorfもこの件に関していくつかの素晴らしいブログ記事を書いています。

動作中

実際にあなたのコードに関して、あなたは2つのアプローチを混在させました;-)これがそれらです:

  • 自分自身で観測量を管理する 。この場合、あなたはオブザーバブルのsubscribeメソッドを呼び出し、結果をコンポーネントの属性に代入する責任があります。その後、コレクション内で反復するためにビュー内でこの属性を使用できます。

    @Component({
      template: `
        <h1>My Friends</h1>
        <ul>
          <li *ngFor="#frnd of result">
            {{frnd.name}} is {{frnd.age}} years old.
          </li>
        </ul>
      `,
      directive:[CORE_DIRECTIVES]
    })
    export class FriendsList implement OnInit, OnDestroy {
      result:Array<Object>; 
    
      constructor(http: Http) {
      }
    
      ngOnInit() {
        this.friendsObservable = http.get('friends.json')
                      .map(response => response.json())
                      .subscribe(result => this.result = result);
       }
    
       ngOnDestroy() {
         this.friendsObservable.dispose();
       }
    }
    

    getメソッドとmapメソッドの両方からの戻り値は結果ではなく観測可能です(promiseと同じ方法で)。

  • Angular template で観測量を管理しましょう。 asyncパイプを利用して、オブザーバブルを暗黙的に管理することもできます。この場合、subscribeメソッドを明示的に呼び出す必要はありません。

    @Component({
      template: `
        <h1>My Friends</h1>
        <ul>
          <li *ngFor="#frnd of (result | async)">
            {{frnd.name}} is {{frnd.age}} years old.
          </li>
        </ul>
      `,
      directive:[CORE_DIRECTIVES]
    })
    export class FriendsList implement OnInit {
      result:Array<Object>; 
    
      constructor(http: Http) {
      }
    
      ngOnInit() {
        this.result = http.get('friends.json')
                      .map(response => response.json());
       }
    }
    

あなたは観測量が怠惰であることに気付くことができます。そのため、対応するHTTPリクエストは、subscribeメソッドを使用してリスナーにアタッチされたリスナーに対して一度だけ呼び出されます。

また、応答からJSONコンテンツを抽出して観察可能な処理に使用するためにmapメソッドが使用されていることもわかります。

これがあなたに役立つことを願っています、ティエリー

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

HttpClient APIは、バージョン4.3.0で導入されました。これは既存のHTTP APIの発展形であり、独自のパッケージ@ angular/common/httpを持っています。最も注目すべき変更点の1つは、応答オブジェクトがデフォルトでJSONになったことです。そのため、これをmapメソッドで構文解析する必要はもうありません。

http.get('friends.json').subscribe(result => this.result =result);
11
rajesh kumar