我在一個應用程序中顯示有關'Modyules'(在課程中)必須通過兩個http.gets(我不能控制apis不幸)的信息:通過在ng2中的可觀察對象的依賴和並行請求
- 獲取Modyule.ids列表 - 需要存儲的ID
- 對於每個Modyule.id另一個http.get得到Modyule.name
在我modyule.component.ts ,我有:
this.modyuleService.getModyules()
.subscribe(
modyules => this.modyules = modyules,
error => this.errorMessage = <any>error
);
在我modyule.service.ts,我有:
getModyules(): Observable<Modyule[]> {
return this.http.get(listOfModyuleIdsUrl + '.json')
.map(this.getModyulesDetails)
.catch(this.handleError);
}
但getModyuleDetails是我很努力。這是我有這麼遠,主要是基於:
http://www.syntaxsuccess.com/viewarticle/angular-2.0-and-http
,看着,但沒有看到我如何申請:
https://stackoverflow.com/a/35676917/2235210
private getModyulesDetails = (res: Response) => { // instance method for defining function so that the this.http below refers to the class.
let listOfModyules = res.json();
let modyulesToReturn = [];
for (let individualModyule of listOfModyules){
let tempModyule = new Modyule;
tempModyule.id = individualModyule.id;
this.http.get(individualModyuleUrl + individualModyule.id + '.json')
.map((res: Response) => res.json()))
.subscribe(res => {
tempModyule.name = res.name
modyulesToReturn.push(tempModyule);
});
}
return modyulesToReturn;
}
現在,這是在我的本地機器上工作,在那裏我將.json響應作爲靜態.json文件來模擬。但是,當我處理真正的api時,我無法依賴for循環中的http.gets完成在返回modyulesToReturn之前。
我已經在forkJoin上做了幾次嘗試,但沒有看到如何將它與需要從第一個http.get捕獲Modyule.id的要求結合起來。
我非常感謝任何有關如何執行並行請求的指針,這些請求依賴於初始請求,但能夠將來自兩者的數據組合起來。
編輯在向效應初探討論,@馬特和@batesiiic:
因此,在@ batesiiic的建議getModyulesDetails的重寫拿起返回一個主題,我不能讓我的頭周圍的問題是如何填充在Modyule.id在第一個呼叫,然後Modyule.name在第二次調用(不返回任何Modyule.id參考),即:
private getModyulesDetails = (res: Response) => { // instance method for defining function so that the this.http below refers to the class.
let listOfModyules = res.json();
let modyulesToReturn = [];
let calls = [];
for (let individualModyule of listOfModyules){
/* I REALLY NEED TO POPULATE Modyule.id HERE */
calls.push(
this.http.get(individualModyuleUrl + individualModyule.id + '.json')
.map((res: Response) => res.json()))
);
}
var subject = new Subject<Modyules[]>();
Observable.zip.apply(null, calls).subscribe((modyules: Modyules[]) => {
var modyulesToReturn = [];
modyules.forEach(modyule => {
let tempModyule = new Modyule;
/*I COULD POPULATE Modyle.name HERE BUT IT WON'T MATCH THE Modyule.id SET ABOVE - EXCEPT BY LUCK*/
modyulesToReturn.push(tempModyule);
}
subject.next(modyulesToReturn);
});
return subject;
}
我想我需要打的電話一個通過for循環中的一個,但以某種方式等待,直到他們已經迴應modyulesToReturn之前所有響應?
感謝@馬特。我可能會誤解,但這不是我通過在地圖回調(在服務中)中調用getModyulesDetails中的細節來收集有效信息嗎?我仍然不確定如何讓getModyule等到getModyuleDetails(即使插入的地方你提出作爲一個服務方法,它自己的訂閱回調)已經返回...做一個.subscribe回調,其中包含另一個.subscribe回調有等到第二次訂閱被調用? – theotherdy
謝謝@Matt。你的解釋非常清楚。 batesiiic +例如http://stackoverflow.com/a/38156976/2235210建議使用Rx.Subjects,但我真的不明白這是如何工作的。我是否正確地閱讀你所說的,因爲我應該避免單個組件中的這些依賴/鏈接請求,而是創建例如觀察Observable getModyulesDetails方法的ModyuleDetailComponent?在這種情況下,我該如何讓ModyuleDetailComponent知道ModyuleComponent已經完成獲取Modyule.ids的列表,以便我可以例如@Input()他們到ModyuleDetailComponent? – theotherdy
這取決於。 batesiiic的方法是將所有東西都捆綁在一起,這樣Subject/Observable就會觸發一次。如果你訂閱它,你會得到完整的細節清單。另一種方法是每當你從服務器得到響應時,將細節發送給你的組件。然後Subject/Observable會多次激發。如果你有大量的modyule,並且你寧願向用戶展示前10個,而不是讓他等到所有1000個已經加載(比方說),那麼這會很有用。 - batesiiic的代碼提供了實現這兩種方法的想法。 – Matt