2017-07-25 59 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