2017-02-24 104 views
1

我創建了3個Angular2服務,可從不同的http端點檢索類別,位置和項目。我現在想創建一個新的服務,從這些服務中檢索數據,並從檢索到的所有數據創建一個新的DataSet,但我無法從非迭代的DataSet對象創建Observable。非陣列類型可觀察

有沒有更好的方法來將數據整合到單個結構中,例如使用Observables?

export class DataSet { 
    items: Item[]; 
    locations: Location[]; 
    categories: Category[]; 
} 

@Injectable() 
export class DataService { 

_data : DataSet; 

constructor(
    private _http: Http, 
    private _categoryService: CategoryService, 
    private _locationService: LocationService, 
    private _itemService: ItemService) { } 

getDataSet(): DataSet { 
    this._data = new DataSet(); 

    this._categoryService.getCategories().subscribe(cats => { 
     this._data.categories = cats; 
    }); 

    this._locationService.getLocations().subscribe(locs => { 
     this._data.locations = locs; 
    }); 

    this._itemService.getItems(null).subscribe(items => { 
     this._data.items = items; 
    }); 

    // ERROR can't create observable from non array type dataset 
    return Observable.from(this._data); 
    } 
} 

回答

1

是的,你需要明確使用

import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/observable/of'; 

UPDATE使用Observable.of作爲

return Observable.of(this._data); 

您可能需要添加導入的功能:

正如所指出的,我對我的回答不滿意在評論中並沒有解決潛在的問題。所以我添加了一個解決方案

import 'rxjs/add/observable/forkJoin'; 
import {Observable} from 'rxjs/Observable'; 

export class DataService { 

    constructor(
    private http: Http, 
    private categoryService: { getCategories(): Observable<{ categoryName: string }[]> }, 
    private locationService: { getLocations(): Observable<{ locationName: string }[]> }, 
    private itemService: { getItems(options): Observable<{ itemName: string }[]> }) { } 

    getDataSet() { 
    return Observable 
     .forkJoin(
     this.categoryService.getCategories(), 
     this.locationService.getLocations(), 
     this.itemService.getItems(undefined) 
    ) 
     .map(([categories, locations, items]) => ({ 
     categories, 
     locations, 
     items 
     })); 
    } 
} 

Observable.forkJoin有您正在尋找的,因爲它由他們將測序得到的結果陣列的方式保留了不同的輸入觀測量之間的區別的語義。

請注意,這樣會清除我們的代碼,因爲不再有可變的類字段。

只是一些想法:

東西我覺得有趣的是,我不得不使用Observable.forkJoin(有可能是一個更簡單的方法,並告訴我如果有!),這是不是一個非常發現功能,也碰巧在ForkJoinObservable.d.ts沒有文檔。

這讓我感到困擾的原因是,這個問題描述了使用Observable作爲單數 Web請求的接口的基本場景。如果我們相信Observable是這個用例的正確抽象,它應該是明顯而直觀的。一旦我們討論類型前輸入,這些異步查詢會隨着時間的推移在0和某些任意n值之間返回,那麼是的,Observable嵌入Web請求似乎會變得有價值。

唯一的問題在於,類型爲RxJS + Angular的海報子的typeahead場景涉及到flatMapping無論如何。整個抽象被提升到RxJS已經適用,相關且優雅的水平,因爲域是流的域。

+0

感謝Aluan,您回答了有關Observable.of的問題,但沒有達到預期的結果。我期待的訂閱者將不會被調用,直到嵌套集合填充,但我想我需要看看可觀察的鏈接。 – Dennis

+0

這是正確的。您可以使用合併或分叉連接或concat。一切都不一樣。 –

+0

當然,在RxJS中也有幾十種其他方法可以做到這一點。不幸的是,最明顯的方式是用地圖調用代替所有的訂閱調用,然後嵌套,這將導致代碼不可讀。 –