2016-02-11 47 views
7

獲得項目給出下面的打字稿在角2服務:角2的方式從可觀察<Xyz[]>

getLanguages() { 
    return this.http.get(this._languagesUrl) 
     .map(res => <Language[]> res.json().data) 
     .catch(this.handleError); 

我遇到的情況使用這個,我需要從數組中查找特定項目的難度。例如,我不能執行以下操作,因爲filter需要Observable<Language>而不是正在返回的Observable<Language[]>

getLanguages().filter(language => language.id == 3) // Error 

我很感激我的問題可能是我在混合同步和異步行爲,因此不適提供我的使用情況:用戶可以輸入語言ID,我想顯示相關的語言名稱。我想利用getLanguages()Observable結果,因爲它已經在項目的其他地方使用。我也希望實現一些緩存,以便每次查找時都不會獲得HTTP請求。

有什麼想法?

+1

你得到了什麼確切的錯誤? – Langley

回答

2

這裏有一個例子,你想要做什麼工作:

https://plnkr.co/edit/lK47pVaW8b0CEez0mum4?p=preview

在chrome中按F12查看日誌,以便更清楚地瞭解發生了什麼以及爲什麼它在您的示例中不起作用。

採取特殊atention到:

constructor(private _langService: LanguagesService) { 
    _langService.getLanguages() //We get an Observable<Array> object returned. 
     //So this is the observable's filter function: 
     .filter(this._filter3rdLanguage) 
     //The filter gets called only once and its comparing an observable object, not a language object. 
     //that's why nothing gets filtered: 
     .do(o => console.log(o)) 
     //If you filter the actual list instead of the observable object, you'll get it called several times. 
     //This is the Array's filter function. 
     .subscribe(list => this.languages = list.filter(this._filter3rdLanguage)); 
} 

這又是一個,也許更好,辦法做到這一點:

_langService.getLanguages() 
    .map(list => list.filter(this._filter3rdLanguage)) 
    //see that this one IS filtered. 
    .do(list => console.log(list)) 
    .subscribe(list => this.languages = list); 
+0

謝謝!以這種方式將項目記錄到控制檯幫助我看到,我只獲取一個對象,該對象是我想要過濾的對象的數組。 – theUtherSide

0

這是一個猜測,因爲我沒有親自使用RxJS,儘管我對它感興趣。仔細閱讀該文檔,不知下面將工作:

function getLanguageName(id: number): Observable<string> { 
    return getLanguages() 
       .map((langs: Language[]) => _.find(langs, { id: id })) 
       .pluck('name'); 
} 

我用Lodash的_.find()找到數組中的匹配記錄,但如果你沒有它,你可以隨時手動或使用做搜索.filter(langs, ...)[0]

如果您想要進行緩存,並且您知道某個給定ID的語言名稱將永遠不會改變,您可以使用Lodash的_.memoize()函數爲給定輸入重用輸出。

我很好奇,看看這是否適合你。

1

如果按照mapsubscribe,您可以訪問Language陣列的成員時,陣列可用:

return this.http.get(this._languagesUrl) 
    .map(res => <Language[]> res.json().data) 
    .subscribe((languages: Language[]) => alert(languages[3]);); 
2

可以使用mergeMap,而不是map拉平數組:

getLanguages() { 
    return this.http.get(this._languagesUrl) 
     .flatMap(res => Rx.Observable.fromArray(<Language[]> res.json().data)) 
     .catch(this.handleError); 

} 

現在來自的返回值將在可觀測<類型>

let item: Language; 
    langugages. // observable cached data 
     .subscribe((items: Language[]) => item = items.find(p => p.id == 3)); 
8

發現項目,我需要一種方法來隱藏或者顯示的按鈕取決於是否一個用戶帳戶有一個特定的業務線,我需要對正在加載到頁面上的異步數據採取行動,而不一定按原樣使用這些數據。所以我從模板中調用一個方法,然後使用map和find來訂閱。

 <button *ngIf="(lobs$ | async) ? getButtonVisibility('internet') : false" class="eing-account-header-drawers-button" (click)="openDrawer(drawers[drawers.internet],$event)"> 


public getButtonVisibility(lobName: string) { 
    let isVisible; 
    this.lobs$.map(x => 
    x.findIndex(y => 
     y.lobName.toLowerCase() == lobName.toLowerCase() && y.hasLob)) 
     .subscribe(x => { isVisible = x != -1}); 
    return isVisible;  
} 
0

對於客戶服務的應用程序,我支持一個Observable<Language>