2017-07-25 60 views
0

我正在使用服務在服務器上上傳圖像。這裏是:Angular 2&Vanilla JS:在進行http調用之前等待圖像加載

addPictures(files: File[], folder: string): Observable<Parse.Object[]> { 
    let hasError = false; 
    for (let file of files) { 
    let [type, ext] = file.type.split('/'); 
    if (type.toLowerCase() !== 'image' || !environment.imgExts.includes(ext.toLowerCase())) { hasError = true; } 
    } 
    if (hasError) { return Observable.throw('Invalid extension detected'); } 

    let observables: Observable<Parse.Object>[] = []; 

    for (let file of files) { 
    // Get its size 
    let img = new Image(); 
    img.onload =() => { 
     // Create the Parse document 
     let parseImg = { url: '', type: file.type, width: img.width, height: img.height }; 
     // Upload it on Amazon and add it to DB 
     observables.push(this.addPicture(parseImg, file, folder)); 
     console.log('pushing to array'); 
    } 
    img.src = window.URL.createObjectURL(file); 
    } 
    console.log('forkjoin'); 
    return Observable.forkJoin(observables); 
} 

所有的功能都很好。我面臨的問題是,當我使用img.onload時,forkJoin不會在發射前等待它。我想要的是等待所有的圖像加載,然後觸發thr forkJoin發送它們全部

我已經嘗試了一個條件(當最後一項被推入數組,觸發forkJoin),但是問題是我的組件按照Cannot read property 'subscribe' of undefined的順序返回錯誤。這裏

編輯是我的蘇氨酸fromEvent代碼:

addPictures(files: File[], folder: string): Observable<Parse.Object[]> { 
    let hasError = false; 
    for (let file of files) { 
    let [type, ext] = file.type.split('/'); 
    if (type.toLowerCase() !== 'image' || !environment.imgExts.includes(ext.toLowerCase())) { hasError = true; } 
    } 
    if (hasError) { return Observable.throw('Invalid extension detected'); } 

    let observables: Observable<Parse.Object>[] = []; 

    for (let file of files) { 
    // Get its size 
    let img = this.fromImgEvent(file, window.URL.createObjectURL(file), folder); 
    observables.push(img); 
    } 
    console.log('forkjoin'); 
    return Observable.forkJoin(observables); 
} 

fromImgEvent(file: File, url: string, folder: string) { 
    return Observable.create(observer => { 
    let img = new Image(); 
    img.onload =() => { 
     // Create the Parse document 
     let parseImg = { url: '', type: file.type, width: img.width, height: img.height }; 
     // Upload it on Amazon and add it to DB 
     observer.next(this.addPicture(parseImg, file, folder)); 
     observer.complete(); 
    } 
    img.src = url; 
    }); 
} 
+0

你有沒有嘗試'Observable.fromEvent'操作符來監聽onload ev作爲可觀察的。 – cyrix

+0

不,我不知道這個,你能舉個快速的例子嗎? – trichetriche

回答

0

您可以通過自己的加載圖像使用例如Observable.fromEvent或創建一個可觀察到,像這樣:

addPictures(files: File[], folder: string): Observable<Parse.Object[]> { 
 
    let hasError = false; 
 
    let data$ = files.map(file => { 
 
    let [type, ext] = file.type.split('/'); 
 
    if (type.toLowerCase() !== 'image' || !environment.imgExts.includes(ext.toLowerCase())) { 
 
     hasError = true; 
 
    } 
 
    return Observable.create(observer => { 
 
     let image = new Image(); 
 
     image.src = window.URL.createObjectURL(file); 
 
     image.onload = (e) => { 
 
      let parsedImage = { url: '', type: file.type, width: image.width, height: image.height }; 
 
      observer.next({ parsedImage, file }); 
 
      observer.complete(); 
 
     }; 
 
    }); 
 
    }; 
 
    if (hasError) { 
 
    return Observable.throw('Invalid extension detected'); 
 
    } 
 
    return Observable 
 
    .forkJoin(data$) 
 
    .toArray() 
 
    .switchMap(([parsedData]) => { 
 
     return Observable.forkJoin(
 
      parsedData.map(data => { 
 
       return this.addPicture(data.parsedImage, data.file, folder) 
 
      }) 
 
     ); 
 
    }); 
 
}

+0

剛剛測試過它,並且在observable的數組有值之前,forkjoin仍然被激怒... – trichetriche

+0

你可以在測試用例中添加一個plunkr嗎?或者將這個擴展添加到問題中? – cyrix

+0

等待我忘了實際使http呼叫哈哈。我加入並測試,我會讓你知道! – trichetriche

相關問題