2016-11-22 15 views
1
import { Injectable }  from '@angular/core'; 
import { Http, Response, Headers, RequestOptions } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 

// Import RxJs required methods 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch' 

@Injectable() 
export class EquipmentService{ 
    data: any; 
    constructor(private http:Http){ 

    } 
    getDefaultEquipment(){ 
     this.http.get('./app/SaveData/equipmentTest.json') 
      .map((res:Response) => res.json()) 
      .subscribe(data => { this.data = data}, 
       err => console.error(err), 
       () => console.log(this.data)); 
    } 
} 

重要なビットはgetDefaultEquipment()です。角度2が観測可能どのように応答を抽出するのですか?

最後のconsole.log(this.data)が表示されていれば、データは正確です。これは私が必要とするものです。しかし、私はreturn this.http.get(...() => {return this.data})私は未定義になる場合。私はどのように取得し、this.dataを返すのですか?

明らかに、次のような別のリターンを書き込むと、オブザーバブルがまだ完了していないため、空のデータが返されます。

//clearly won't work because the get hasn't returned yet 
getDefaultEquipment(){ 
    this.http.get(...data => {this.data = data}...); 
    return this.data; 
} 
+0

あなたの観測値を返すだけです。非同期コールを同期コールに変換する必要はありません。 – Cleiton

+0

データを返すことはできません。購読しないでください。観測可能なものを返すだけです。呼び出し元はサブスクライブするものになり、subscribe()に渡されたコールバック関数内のデータを取得します。 –

+0

それがトリックでした。私の機器コンポーネント 'this.equipmentService.getDefaultEquipment()。subscribe( stuff => {console.log(stuff)}、 )の呼び出し側にsubscribeメソッドを追加しました。 –

答えて

4

以下は私の取り組みです。テストされていませんが、コンセプトは堅実です。これは、基本的にObservablesを食べているasyncパイプのために、定型コードをたくさん節約できます。いくつかの変換を行う必要がある場合は、オブザーバブルを返す前にも可能です。あなたはサービスの中でそれを行うこともできるし、コンポーネント内で行うこともできます。 Observablesについて覚えておいてください。複数のユーザがいる場合は.share()演算子を使用してください。そうでなければ、http.getを各サブスクライバに対して1回実行してください。同じことが便利になることができる.do演算子のために行くだけでなく、加入者のように動作します。

RxJを読んで、非同期パイプの使用に関する角度ウェブサイトの例を見てみることをお勧めします。

角度AsyncPipeは不純なパイプの興味深い例です。 AsyncPipeはPromiseまたはObservableを入力として受け取り、入力に自動的にサブスクライブし、最終的に放出された値を返します。

equipment.service.ts

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Rx'; 

export interface Equipment { 
    name: string; 
    id: string; 
} 

@Injectable() 
export class EquipmentService { 

    constructor(private http:Http){} 

    public getDefaultEquipment(): Observable<Equipment[]> { 
    return this.http 
    .get('./app/SaveData/equipmentTest.json') 
    .map((res:Response) => res.json()); 
    } 
} 

機器-list.component.ts

import { Component, OnInit } from "@angular/core"; 
import { EquipmentService, Equipment } from "./services/equipment.service"; 
import { Observable } from 'rxjs/Rx'; 

@Component({ 
    selector: 'equipment-list', 
    templateUrl: './equipment-list.component.html', 
    styleUrls: ['./equipment-list.component.css'], 
    providers:[ 
    EquipmentService 
    ] 
}) 
export default class EquipmentComponent { 

    constructor(private service: EquipmentService) {} 

    public get equipment():Observable<Equipment[]> { 
     return this.service.getDefaultEquipment(); 
    } 
} 

機器-list.component.html

<ul> 
    <li *ngFor="item of (equipment | async)> 
     <span>{{item.id}}</span> 
     <span>{{item.name}} 
    </li> 
</ul> 
+3

回答は、説明がある場合に最も適しています。単に「これを行う」と言っても、なぜそれがそのように機能するのかを理解するのには役立ちません。同様の状況が発生した場合、私たちを助けません。 –

+1

申し訳ありません。ミスクリックがあり、説明が完了する前に投稿されました。 – abdavid

+0

@abdavidの答えは正しいですが、私がコンポーネントに**反応させたいので、 '.map((res:Response)=> res.json());レスポンスに:ヘッダ、ステータスコードなどを読み込みます。 – Aitch

関連する問題