【发布时间】:2018-03-29 17:34:05
【问题描述】:
我知道这个问题已经被问过几次了,但我找不到在 Angular 5 和 rxjs5 中实际工作的解决方案。
TL;DR; 如何让这 4 个 observables 依次同步运行:
const getImage$ = this.fileService.getImage(this.shape.imageFile.id);
const getUrl$ = Observable.create((blob: Blob) => {
return URL.createObjectURL(blob);
});
const fromURL$ = Observable.bindCallback(fabric.Image.fromURL);
const addImage$ = Observable.create((img: any) => {
this.shapeElement = img;
this.shapeGroup = new fabric.Group([this.shapeElement], {
lockScalingFlip: true,
centeredRotation: true,
angle: this.shape.rotation
});
this.fabric.add(this.shapeGroup);
} );
然后返回 Observable,以便我可以在订阅者中做更多事情。
更长的版本...
我有一个文件服务请求图像并返回 blob 的 observable:
getImage(id) => Observable<Blob>
然后我需要获取此 blob 的 url:
URL.createObjectURL(blob)
然后我需要将它加载到 FabricJS 画布中,该画布有一个带有回调的函数。我从中创建并观察到:
fromURL = Observable.bindCallback(fabric.Image.fromURL)
最后,在我返回 observable 之前,我需要处理 Fabric 创建的图像对象 - 订阅有更多内容来更新 ui。
this.shapeGroup = new fabric.Group([this.shapeElement], {
lockScalingFlip: true,
centeredRotation: true,
angle: this.shape.rotation,
tag: Date.now()
});
this.shapeGroup.shapeView = this;
this.shapeGroup.setShadow(this.getShadow());
this.canvas.fabric.add(this.shapeGroup);
这是我迷路的地方。我试图理解 mergeMap 和 map 和 pipe 以及其他一些东西,但我无法让它工作。
这里有人做过这种事吗?这似乎实现起来过于复杂。
我已经开始这样做了:
draw(): Observable<ImageView> {
const fromURLOb = Observable.bindCallback(fabric.Image.fromURL);
return Observable.create(o => {
if (this.shape.imageFile) {
console.log('started loading');
o.next(this.fileService.getImage(this.shape.imageFile.id));
}
o.complete();
})
...
这行得通,但在我迷路之后。
解决方案!
感谢@Ingo,这是我的工作版本。
draw(): Observable<ImageView> {
return this.fileService.getImage(this.shape.imageFile.id)
.map(blob => URL.createObjectURL(blob))
.switchMap<string, any>(url => {
return Observable.bindCallback(fabric.Image.fromURL).call(this, url);
})
.do<ImageView>(image => {
this.handleImage(image);
return this;
});
}
【问题讨论】: