2017-02-24 183 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中也有几十种其他方法可以做到这一点。不幸的是,最明显的方式是用地图调用代替所有的订阅调用,然后嵌套,这将导致代码不可读。 –