我有一個名爲'Item'的模型類,需要從後端加載兩個單獨的圖像(精確到精靈紋理和陰影紋理)。我實現了並行加載並將紋理最終加入到我的項目中,以便我可以在另一個地方簡單地訂閱它。鏈加入observables到一個訂閱
現在,當我使用Base64將文件傳輸到我的Angular2應用程序時,我已經有了這個工作。但是現在我想和普通的blob一起工作。儘管Angular2尚不支持這種方式,但完全可以讀取響應的private _body屬性。問題是我的模型類應該檢索圖像爲HTMLImageElements
,並將數據解析爲Base64數據網址。要從我的blob生成這個數據url,我需要使用基於回調工作的FileReader.readAsDataUrl()
。我想我已經想出瞭如何將這個回調包裝成一個Observable(如果這種方法是錯誤的,請糾正我,因爲我現在無法確認它)。
所以,現在我根本無法弄清楚如何正確連鎖我的電話,以便能夠訂閱導致可觀察,然後產生我的項目,這樣ItemService.getItem(1).subscribe(item => ...)
當前的設置給了我一個奇怪的錯誤,說明該訂閱方法未在生成的Observable上定義。我很新的RxJS,並會非常高興,如果有人能告訴我如何正確地設置此:)
/* implementation in ItemService */
getItem(id:number):Observable<Item> {
return Observable.forkJoin(// join both texture fetches
this.http.get('/api/items/' + id + '/sprite'), // fetch sprite texture
this.http.get('/api/items/' + id + '/shadow'), // fetch shadow texture
(spriteResponse, shadowResponse) => {
// transform responses into proper blobs
const spriteBlob = new Blob([spriteResponse._body], {type: 'image/png'})
const shadowBlob = new Blob([shadowResponse._body], {type: 'image/png'})
return [spriteBlob, shadowBlob]
})
.flatMap(result => Observable.forkJoin(// chain with joined image generation (pretty sure this is wrong somehow)
ItemService.generateImage(result[0]), // parse spriteBlob to image
ItemService.generateImage(result[1]), // parse shadowBlob to image
(spriteImage, shadowImage) => {
// assemble model from images
const item = new Item()
item.setSprite(spriteImage)
item.setShadow(shadowImage)
return item
})
)
}
static generateImage(data:Blob):Observable<HTMLImageElement> {
const img = new Image() // create new HTML Image
const reader = new FileReader() // init file reader
reader.readAsDataURL(data) // transform blob to base64 data url
// create observable from callback (is this correct?)
return Observable.bindCallback(reader.onloadend,() => {
img.src = reader.result
return img
})
}
謝謝,圖像現在被正確解析,但第二個fork-join的選擇器(其中從事件創建的observable)被加入不會被調用,你知道爲什麼嗎?我正在使用正確的方法調用flatMap嗎? – nilo
啊,是的,問題在於'forkJoin'等待源文件完成才發出,'fromEvent'沒有完成,所以你需要添加'first'或'take(1)'。 – paulpdaniels