在我的Angular 5应用程序中,我有一个文件上传组件,它获取页面上放置的文件列表,并为每个文件调用文件上载服务。我想在上传或拒绝所有文件时显示错误列表。
我有这样的事情:
Observable.from(files).subscribe(file=> {
if (file.size > this.MAX_SIZE) {
errors.push(`${file.name} is too large.`);
} else if (this.validFileTypes.indexOf(file.type) < 0) {
errors.push(`${file.name} is is not a valid image file.`);
} else {
this.uploading = true;
this.uploadingFile = file.name;
this.fileService.uploadFile(file)
.subscribe((ev: any) => {
if (ev.type === HttpEventType.UploadProgress) {
// blah blah
} else {
this.uploading = false;
}
}, (err: any) => {
errors.push(err);
}
);
});
},
err => {},
() => {
if (errors.length) {
console.log('there were errors');
}
});
问题是subscribe()完全回调在其他任何事情之前被调用,甚至在它进行主回调之前。
我仍然对这个rx / js的东西感到困惑,所以我确定我再次做了一些愚蠢的事情,但这需要很长时间才能解决。
感谢您阅读此内容:)
更新1
我尝试了@Miller的第一个建议,但现在收到错误:
无法阅读财产&#39;申请&#39;未定义的
我的新方法是:
class DroppedFile {
constructor(public droppedFile: any, public error: any) { }
}
public dropped(event: UploadEvent) {
const uploads: any[] = event.files.map(evf => new DroppedFile(evf, null));
const subs = new Array<any>();
uploads.forEach(upload => {
if (upload.droppedFile.fileEntry.isFile) {
const fileEntry = upload.droppedFile.fileEntry as FileSystemFileEntry;
fileEntry.file((file: File) => {
if (file.size > this.MAX_SIZE) {
upload.error = `${file.name} is too large. Maximum file size is ${this.MAX_SIZE / 1024}KB.`;
} else if (this.validFileTypes.indexOf(file.type) < 0) {
upload.error = `${file.name} is is not a valid image file. You can only upload JPG, GIF & PNG files.`;
}
});
}
});
uploads.filter(upload => upload.error == null).forEach(upload => {
const fileUpload$ = this.fileService.uploadFile(upload.droppedFile, upload.droppedFile.relativePath)
.catch((err: any, cort: Observable<any>) => {
upload.error = err;
return null;
});
subs.push(fileUpload$);
});
if (subs.length > 0) {
Observable.forkJoin(...subs) // BANG! Cannot read property 'apply' of undefined
.subscribe((ev: any) => {
this.uploading = true;
if (ev.type === HttpEventType.UploadProgress) {
this.uploadingPercentage = Math.floor(ev.loaded * 100 / ev.total);
} else {
this.uploading = false;
}
}, (err: any) => {
// errors.push(err);
},
() => {
// display any errors
this.getPage(0);
this.showErrors(uploads);
});
} else {
this.showErrors(uploads);
}
}
答案 0 :(得分:0)
问题是您的外部订阅不等待uploadFile
来电。
要解决此问题,您可以将fileUpload调用的结果组合到一个数组中。然后使用forkJoin ...
等待他们全部完成const fileUploads: Observable<any>[] = [];
const errors = [];
files.forEach(file => {
if (file.size > this.MAX_SIZE) {
errors.push(`${file.name} is too large.`);
} else if (this.validFileTypes.indexOf(file.type) < 0) {
errors.push(`${file.name} is is not a valid image file.`);
} else {
const fileUpload$ = this.fileService.uploadFile(file)
.catch((err: any) => {
errors.push(err);
});
fileUploads.push(fileUpload$);
}
});
this.uploading = true;
Observable.forkJoin(...fileUploads).subscribe(
() => {},
err => {},
() => {
this.uploading = false;
if (errors.length) {
console.log('there were errors');
}
})
);