Angular 在非数组类型上可观测
我已经创建了3个Angular2服务,它们从不同的http端点检索类别、位置和项目。我现在想创建一个新的服务,从这些服务中检索数据,并从所有检索到的数据中创建一个新的数据集,但我无法从不可iterable的数据集对象创建一个可观察的数据集 有没有更好的方法将数据整合到一个单一的结构中,比如在使用可观测数据时Angular 在非数组类型上可观测,angular,observable,angular2-services,reactive,Angular,Observable,Angular2 Services,Reactive,我已经创建了3个Angular2服务,它们从不同的http端点检索类别、位置和项目。我现在想创建一个新的服务,从这些服务中检索数据,并从所有检索到的数据中创建一个新的数据集,但我无法从不可iterable的数据集对象创建一个可观察的数据集 有没有更好的方法将数据整合到一个单一的结构中,比如在使用可观测数据时 export class DataSet { items: Item[]; locations: Location[]; categories: Category[]; } @
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);
}
}
是的,您需要使用中的
return Observable.of(this._data);
您可能需要使用显式添加函数的导入
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
更新:
我对我的回答不满意,正如评论中指出的那样,它并没有解决根本问题。因此,我添加了一个解决方案
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
}));
}
}
导入'rxjs/add/observable/forkJoin';
从“rxjs/Observable”导入{Observable};
导出类数据服务{
建造师(
私有http:http,
私有categoryService:{getCategories():Observable},
私有位置服务:{getLocations():Observable},
私有项服务:{getItems(选项):可观察的}{}
getDataSet(){
可观测回波
.forkJoin(
this.categoryService.getCategories(),
this.locationService.getLocations(),
this.itemService.getItems(未定义)
)
.map([类别、位置、项目])=>({
类别,
位置,
项目
}));
}
}
Observable.forkJoin
具有您想要的语义,它通过将不同的输入可观察对象排序到结果数组中来保留它们之间的区别
注意,这也清理了我们的代码,不再有可变类字段
只是一些想法:
我发现有趣的是,我不得不使用Observable.forkJoin
(可能有更简单的方法,请告诉我是否有!),这不是一个很容易发现的函数,而且碰巧在ForkJoinObservable.d.ts中也没有文档
这个问题困扰我的原因是,当使用Observable作为单一Web请求的接口时,这个问题描述了一个基本场景。如果我们相信Observable是这个用例的正确抽象,那么它应该是显而易见和直观的
只要我们讨论像typeahead输入这样的东西,这些输入执行异步查询,随着时间的推移返回0到任意的n值,那么是的,可观察到的嵌入Web请求似乎变得很有价值
唯一的问题是,typeahead场景(有点像RxJS+Angular的海报子场景)涉及到结果的平面映射。整个抽象被提升到RxJS已经适用、相关和优雅的级别,因为这个领域是流的领域。谢谢Aluan,你回答了关于可观察的问题,但没有达到预期的结果。我希望在填充嵌套集合之前不会调用订阅服务器,但我认为我需要研究可观察的链接,这是正确的。您可以使用merge、fork join或concat。当然,在RxJS中也有几十种其他的方法可以做到这一点。不幸的是,最明显的方法是用map调用替换所有subscribe调用,然后嵌套,这将导致无法读取代码。@Dennis嘿,我刚刚用完整的解决方案更新了我的答案。