2016-08-28 5 views
0

Angular2でいくつかの実験を行い、サービスが共有の観測可能性を公開する状況を解決する方法について興味があります。あるコンポーネントがデータの取得を担当し、別のコンポーネントがデータの表示を担当します。データを取得するためのAngular2はobservableを共有します

共通HTTPServiceの責任データ

import { Component, OnInit, OnDestroy } from '@angular/core'; 

import { Subscription } from 'rxjs/Subscription'; 


@Component({ 
    moduleId: module.id, 
    selector: 'display', 
    templateUrl: 'display.component.html' 
}) 
export class DisplayComponent { 
    subscription: Subscription; 

    constructor(public service: Service) {} 

    ngOnInit() { 
    // the observable is undefined :(
    this.subscription = this.service.observable$.subscribe(data => { 
     console.log(data); 
    }, 
    error => { 
     // this never gets reached :(
    }) 
    } 
    ngOnDestroy() { 
    // prevent memory leak when component is destroyed 
    this.subscription.unsubscribe(); 
    } 
} 
を表示するための

import { Component, OnInit, OnDestroy } from '@angular/core'; 

import { Service } from '../shared/index'; 


@Component({ 
    moduleId: module.id, 
    selector: 'get', 
    templateUrl: 'get.component.html', 
    providers: [Service], 
}) 
export class GetComponent { 

    constructor(public service: Service) {} 

    submit() { 
    this.service.get(this.url).subscribe(); 
    } 
} 

DisplayComponent責任のデータを取得するための

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 

@Injectable() 
export class Service { 

    subject = new Subject<string[]>; 

    observable$ = this.subject.asObservable(); 

    constructor(private http: Http) {} 

    observable: Observable<string[]>; 

    get(link: string): Observable<string[]> { 
    this.observable$ = this.http.get('myapi.com') 
        .map((res: Response) => this.subject.next(res.json()) 
        .catch(this.handleError); 

    return this.observable$; 
    } 

    /** 
    * Handle HTTP error 
    */ 
    private handleError (error: any) { 
    // In a real world app, we might use a remote logging infrastructure 
    // We'd also dig deeper into the error to get a better message 
    let errMsg = (error.message) ? error.message : 
     error.status ? `${error.status} - ${error.statusText}` : 'Server error'; 
    console.error(errMsg); // log to console instead 
    return Observable.throw(errMsg); 
    } 
} 

GetComponent責任:ここではいくつかのコードがあります

このデザインは正常に動作しますが、エラー処理は例外ですDisplayComponentでは機能しません。またHttpServiceのマップ機能は、また、GetComponentこのthis.service.get(this.url).subscribe();

この種を設計するための適切な方法は何であるように、「購読」していることを非常に適切ではいないようだthis.subject.next(res.json()

かなり右ていないようですものの? 。

observable$ = this.subject.asObservable(); 
this.observable$ = this.http.get('myapi.com') .... // remove this line 

これを行うための正しい方法:どのように私はHttpComponent

答えて

1

あなたのコードによってスローされたエラーを観察するDisplayComponentがサービス$観察できるが、数回変更されたいくつかの問題がある得ることができます Get Component呼び出しをServiceデータを取得する。データがロードされた後、Get Componentはデータと共にData Readyイベントを発行します。 Display Component、およびこのデータを使用するその他のコンポーネントは、イベントが発生したときにDataReadyイベントをリッスンし、データを更新します。

コード私の答えを説明する:

@Injectable() 
export class GetService { 
    /// subject 
    subject = new Subject<string[]>() 

    /// the observable 
    observable = this.subject.asObservable() 


    constructor(private $http: Http) { 

    } 

    /// get data 
    getData() { 
    // not override observable here 
    this.$http.get("api.com") 
     .map(response => response.json()) // map the data 
     .subscribe((data: string[]) => this.subject.next(data), // emit data event 
       error => this.subject.error(error)) // emit error event 
    } 
} 
+0

イベント?私はRxJSを使いたいと思っていました。 – Mike

+0

ええ、あなたのコードは、 'this.subject.asObservable()'から 'this.http.get( 'myapi.com')'に$ observableを変更するだけで、エラーを 'thisにリダイレクトしません。 subject.asObservable() ' –

+0

私はHttpService catch関数で' '' this.subject.error(error) '' 'を実行しようとしました。提案されたソリューションの回答にいくつかのコードを追加できますか? – Mike

関連する問題