【发布时间】:2019-03-05 07:33:09
【问题描述】:
我有一个看起来像这样的表单:
Program Name 和 Description 是响应式表单的一部分。 Feature Image 和 Video(s) 是文件输入。
我有两个提交表单的按钮,另存为草稿和发布。如果所有字段都已填写,包括文件输入,则发布将被启用。另存为草稿始终处于启用状态,并将提交表单。
提交表单时: 我检查是否有特征图像。如果有,我会将其上传到 Firebase 存储桶。我对视频应用相同的检查。如果有视频,我会一一上传到 Firebase 存储桶。这是相同的代码:
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> 的方法,本质上包装了已上传文件的下载 URL。
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$的长度提取视频下载url,然后相应地创建我的Object。但我正在寻找一种更清洁的方式来做到这一点。
我也尝试过使用Observable.create,但对于这个特定的用例无法理解。
根据Buggy的建议,我也尝试了这个:
forkJoin(forkJoin(videoUrls$), featureImageUrl$)
.pipe(
map(([videoUrls, featureImageUrl]) => ({videoUrls, featureImageUrl}))
);
如果同时选择了特色图片和视频,它就可以正常工作。但是,如果我只选择 Feature Image 而不是不选择任何视频,则订阅永远不会到达。
这里有一个Sample StackBlitz 供您参考。
【问题讨论】:
-
forkJoin(forkJoin(videoUrls$), featureImageUrl$) .pipe( map(([videoUrls, featureImageUrl])=>({videoUrls, featureImageUrl})) )合适吗? -
@Buggy,感谢您的评论。让我检查一下。 :)
-
好的。 So it works fine when both the Feature Image file and the videos are selected and then submitted.但是当未选择其中一个时不起作用。在后一种情况下,它会永远卡住,不过我会用这种方法更新问题。非常感谢。 :)
-
@SiddAjmera 好像
featureImageUrl$你还没有分配任何值,你可以尝试分配像let featureImageUrl$: Observable<string> = of('');这样的初始值,这至少足以完成数据流跨度>
标签: angular rxjs observable rxjs6