2017-02-09 18 views
1

我有兩個angular2服務,一個提供數據兩個angular2服務相同的可觀測

@Injectable() 
export class DataService { 

constructor(private http: Http) { } 

public getData(): Observable<Data> { 
    return this.http.get('/api/foo') 
     .map(res => new Data(res.json().data)); 
} 

和一個提供設置

@Injectable() 
export class SettingsService { 

constructor(private http: Http) { } 

public getSettings(): Observable<Settings> { 
    return this.http.get('/api/foo') 
     .map(res => new Settings(res.json().settings)); 
} 

從/ API /富的響應是

{ 
    "settings": { 
     ... 
    } 
    "data": { 
     .... 
    } 
} 

這些服務都使用相同的API調用來獲取他們的內容,並且對服務器的調用正在進行兩次數據。

我意識到現有的api在將數據和設置結合在一個消息中並不理想,並且可能最終需要被替換。

與此同時,我的問題是:使用現有的api是否有一種直接的方式來提供數據服務和共享相同API調用的設置服務?是否有一個調用API將數據傳遞給兩個服務,還是每個服務都必須獨立運行?

更新: 我的想法到目前爲止,我需要創建一個基本服務,使實際的http調用,調用此FooService。然後需要將FooService注入到SettingsService和DataService中,然後他們可以分別將FooService的輸出表示爲設置和數據。我卡住的地方是如何將FooService返回的Observable<any>分爲兩個其他Observables,Dataservice中的Observeable<Data>和SettingsService中的Observeable<Settings>?這甚至有可能嗎?

回答

0

看起來像你想要一種方法,通過鍵從對象中動態選擇。這是你想要的?

public getSettings(dataKey): Observable<Settings> { 
    return this.http.get('/api/foo') 
     .map(res => new Settings(res.json()[dataKey]); 
} 
+0

@「西蒙^ h ' - 此時代碼正常工作,響應中既有設置又有數據屬性,並且不需要動態選擇灰。我的問題是如何重構設計,以便只有一個http調用來獲取數據,但是使用該數據提供了兩個服務。 –

0

我想出瞭如何做到這一點。創建一個訪問api的服務,然後使用api服務上的.map()創建設置和數據服務。

首先創建一個訪問底層API的服務:

@Injectable() 
export class ApiService { 

    constructor(private http: Http) { } 

    public getObservable(): Observable<any> { 
     return this.http.get('/api/foo') 
      .map(res => res.json())); 
} 

然後創建兩個服務程序會消耗:

@Injectable() 
export class SettingsService { 

    constructor(private api: ApiService) { } 

    public getSettings(): Observable<Settings> { 
     return this.api.getObservable() 
      .map(res => new Settings(res.settings)); 
    } 
} 

@Injectable() 
export class DataService { 

    constructor(private api: ApiService) { } 

    public getData(): Observable<Data> { 
     return this.api.getObservable() 
      .map(res => new Data(res.data)); 
    } 
}