我有一张类似这样的表格:
这个
Program Name
Description
是反应形式的一部分。以及
Feature Image
和
Video(s)
是文件输入。
我有两个按钮提交表单,另存为草稿和发布。如果填充了所有字段(包括两个文件输入),则将启用发布。“另存为草稿”始终处于启用状态,并将提交表单。
let featureImageUrl$: Observable<string>;
const videoUrls$: Observable<string>[] = [];
// Check if featureImageToUpload was uploaded
if (this.featureImageToUpload) {
featureImageUrl$ = this.fileService.upload(`content/programs/images/${this.utils.generateRandomString()}`, this.featureImageToUpload);
}
// Check if video(s) was/were uploaded
if (this.videosToUpload) {
this.utils.range(this.videosToUpload.length).forEach(fileIndex => {
// tslint:disable-next-line:max-line-length
const videoUrl$ = this.fileService.upload(`content/programs/videos/${this.utils.generateRandomString()}`, this.videosToUpload[fileIndex]);
videoUrls$.push(videoUrl$);
});
}
this.fileService.upload
只是一个返回
Observable<string>
this.utils.range
只是一个基于长度返回数字数组的方法。所以如果长度是4,那么它将返回
[0, 1, 2, 3]
问题是:
Observable
我可以订阅它,得到这样一个结构的对象:
{
featureImageUrl: 'DOWNLOAD URL FOR THE FEATURE IMAGE' || null // null in case the file wasn't uploaded;
videos: [
'DOWNLOAD URL FOR VIDEO 1',
'DOWNLOAD URL FOR VIDEO 2',
'DOWNLOAD URL FOR VIDEO 3',
'DOWNLOAD URL FOR VIDEO 4',
...
] || null // null in case the video(s) were not uploaded;
}
到目前为止我尝试过的事情:
我可以用
forkJoin
这样地:
forkJoin(...videoUrls$, featureImageUrl$)
.subscribe(downloadUrls => {
console.log(downloadUrls);
});
然后根据视频长度提取视频下载网址
videoUrls$
然后相应地创建我的对象。但我在寻找一种更干净的方法。
Observable.create
但对于这个特定的用例,我却无法理解。
Buggy
,我也试过这个:
forkJoin(forkJoin(videoUrls$), featureImageUrl$)
.pipe(
map(([videoUrls, featureImageUrl]) => ({videoUrls, featureImageUrl}))
);
如果同时选择了特征图像和视频,那么它的效果非常好。但如果我只选择功能图像而不选择任何视频,订阅永远达不到。
这里有一个
Sample StackBlitz