在非数组类型上可观察
Observable over a non-array type
我创建了 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);
}
}
是的,您需要使用 Observable.of
,如
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
}));
}
}
Observable.forkJoin
具有您正在寻找的语义,因为它通过将输入 Observable 排序到结果数组中来保留不同输入 Observable 之间的区别。
请注意,这也会清理我们的代码,因为不再有可变 class 字段。
一些想法:
我觉得有趣的是我不得不使用Observable.forkJoin
(可能有更简单的方法,如果有请告诉我!)这不是一个很容易发现的功能,而且恰好没有ForkJoinObservable.d.ts.
中的文档
这让我感到困扰的原因是,这个问题描述了使用 Observable 作为 singular Web 请求的接口时的基本场景。如果我们相信 Observable 是这个用例的正确抽象,它应该是显而易见和直观的。
一旦我们谈论诸如预输入之类的东西,它们会随着时间的推移 return 在 0 和一些任意 n 值之间进行异步查询,那么是的,Observable 注入的 Web 请求似乎变得有价值。
唯一的问题是,typeahead 场景是 RxJS + Angular 的典型代表,无论如何涉及 flatMapping 结果。整个抽象被提升到 RxJS 已经适用、相关和优雅的水平,因为领域是流的领域。
我创建了 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);
}
}
是的,您需要使用 Observable.of
,如
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
}));
}
}
Observable.forkJoin
具有您正在寻找的语义,因为它通过将输入 Observable 排序到结果数组中来保留不同输入 Observable 之间的区别。
请注意,这也会清理我们的代码,因为不再有可变 class 字段。
一些想法:
我觉得有趣的是我不得不使用Observable.forkJoin
(可能有更简单的方法,如果有请告诉我!)这不是一个很容易发现的功能,而且恰好没有ForkJoinObservable.d.ts.
这让我感到困扰的原因是,这个问题描述了使用 Observable 作为 singular Web 请求的接口时的基本场景。如果我们相信 Observable 是这个用例的正确抽象,它应该是显而易见和直观的。
一旦我们谈论诸如预输入之类的东西,它们会随着时间的推移 return 在 0 和一些任意 n 值之间进行异步查询,那么是的,Observable 注入的 Web 请求似乎变得有价值。
唯一的问题是,typeahead 场景是 RxJS + Angular 的典型代表,无论如何涉及 flatMapping 结果。整个抽象被提升到 RxJS 已经适用、相关和优雅的水平,因为领域是流的领域。