2016-07-14 94 views
0

比方說,我有一個服務得到的屬性列表:RxJS和angular2

export class PropertyService { 
    private properties: any; 

    constructor(@Inject(Http) http) { 
     this.http.get('/properties.json') 
     .map((res:Response) => res.json()) 
     .subscribe(
      data => this.properties = data 
     ); 
    } 

    getProperty(property: string) { 
     this.properties[property]; 
    } 
} 

的問題是,當propertiesgetProperty叫尚未加載。 如何讓getProperty等待訂閱來填充數組? 我寧願不返回對組件的訂閱。



編輯:
我試圖paulpdaniels回答,並與pluck工作。但我卡住得很快。 所以基本上我有這個PropertyService返回一個HOST。 我有一個ApiService使用該主機做另一個Ajax調用來獲取數據。

export class PropertyService { 
    private properties: any; 

    constructor(@Inject(Http) http) { 
     this.properties = http.get('/properties.json') 
      .map((res:Response) => res.json()).cache(1); 
    } 

    getProperty(property: string) { 
     this.properties.pluck(property); 
    } 
} 


export class ApiService { 
    private http: Http; 
    private host: string; 

    constructor(@Inject(Http) http, @Inject(PropertyService) propertyService) { 
     this.http = http; 
     this.host = propertyServiceService.getProperty("API.URL"); //Is a subscription 
    } 

    getData(): any { 
     //Here I must subscribe to host, and once available, 
     //use host to do an ajax call that returns another Observable for the component 
    } 
} 

如何實現這一點?

回答

1

簡短的答案是你不能,至少不是沒有引入一些不同步的服務水平。

簡單的事實是,沒有辦法強制阻止行爲,並等待Observable完成,您應該返回Observable,然後您的組件應該知道如何使用。

export class PropertyService { 
    private properties: Observable<any>; 

    constructor(@Inject(Http) http) { 
    this.properties = this.http.get('/properties.json') 
          .map((res:Response) => res.json()) 
          //This will hold onto a cached value of the result 
          //without re-executing 
          .cache(1); 

    } 

    getProperty(property: string) { 
    this.properties.pluck(property); 
    } 
} 

編輯1

弗蘭克·赫伯特曾經寫道(意譯) 「流必須流!」。如果您需要使用嵌套Observables運營商(如flatMap),則可以將這些運算符平鋪爲單個流,您可以繼續鏈接。

export class ApiService { 
    private http: Http; 
    private host: Observable<string>; 

    constructor(@Inject(Http) http, @Inject(PropertyService) propertyService) { 
     this.http = http; 
     this.host = propertyServiceService.getProperty("API.URL"); //Is an Observable 
    } 

    getData(): Observable<any> { 
     return this.host.flatMap(url => this.http.get(url), (_, res) => res.json()); 
    } 
} 
+0

問題是我有嵌套的observable,因爲我需要一個observable的響應來產生一個新的observable –

+0

你只需要繼續擴展Observable,Observable的好處是它們基本上是無限可擴展的。我會用一個例子來更新。 – paulpdaniels

0

你可以做的是觀察到自身從性質觀察到的,.flatMap後,一個http請求返回properties,然後在目的地服務啓動。這意味着像其他答案中提到的那樣引入更多的異步性。 Othr解決方案將通過檢索canActivate路由器防護中的屬性來在app /組件真正開始執行之前解析屬性。在這種情況下,您可以確定當組件調用其他服務的方法時,這些服務依賴於同步可用的屬性,這些屬性已經解決。