在不重新运行指定函数的情况下读取可观察变量的值
Reading value of Observable variable without rerunning assigned function
目前我的 angular 组件中有一个功能,每当我想上传文件列表时 运行。
我既要跟踪上传进度然后清空文件列表,又要跟踪上传进度以获得进度条。
我目前的问题是,当我请求 uploadProgress
的值时,它会重新 运行s this.pictureService.upload(this.selectedFiles)
并上传文件两次。
我的函数目前看起来像这样:
uploadImages() {
// Upload picture and save progress to observable
const uploadProgress: Observable<HttpEvent<HttpUploadProgressEvent>> = this.pictureService.upload(this.selectedFiles);
// Create snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
data: { uploadProgress },
});
// Wait for uploading to be finished and then clear selected files and preview URLs
uploadProgress.subscribe((event: HttpUploadProgressEvent) => {
if (event.loaded === event.total && event.loaded !== undefined) {
this.selectedFiles = null;
this.previewUrls = [];
}
});
}
每次调用 .subscribe 时都会调用可观察对象(参见 here。)
如果您在 openFromComponent 函数中这样做,请考虑不要再次调用 .subscribe,而是像这样:
uploadImages() {
// Upload picture and save progress to observable
const uploadProgress: Observable<HttpEvent<HttpUploadProgressEvent>> = this.pictureService.upload(this.selectedFiles);
// Create snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
data: {
uploadProgress.pipe(tap((event: HttpUploadProgressEvent) => {
if (event.loaded === event.total && event.loaded !== undefined) {
this.selectedFiles = null;
this.previewUrls = [];
}
}))
}
})
}
正如 Martin 所建议的,我在常量末尾添加了 .pipe(share())
,现在它可以正常工作了。
我的代码现在看起来像这样:
uploadImages() {
// Upload picture and save progress to observable
const uploadProgress = this.pictureService.upload(this.selectedFiles).pipe(share());
// Create snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
data: { uploadProgress },
});
// Wait for uploading to be finished and then clear selected files and preview URLs
uploadProgress.subscribe((event: HttpUploadProgressEvent) => {
if (event.loaded === event.total && event.loaded !== undefined) {
this.selectedFiles = null;
this.previewUrls = [];
}
});
}
目前我的 angular 组件中有一个功能,每当我想上传文件列表时 运行。
我既要跟踪上传进度然后清空文件列表,又要跟踪上传进度以获得进度条。
我目前的问题是,当我请求 uploadProgress
的值时,它会重新 运行s this.pictureService.upload(this.selectedFiles)
并上传文件两次。
我的函数目前看起来像这样:
uploadImages() {
// Upload picture and save progress to observable
const uploadProgress: Observable<HttpEvent<HttpUploadProgressEvent>> = this.pictureService.upload(this.selectedFiles);
// Create snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
data: { uploadProgress },
});
// Wait for uploading to be finished and then clear selected files and preview URLs
uploadProgress.subscribe((event: HttpUploadProgressEvent) => {
if (event.loaded === event.total && event.loaded !== undefined) {
this.selectedFiles = null;
this.previewUrls = [];
}
});
}
每次调用 .subscribe 时都会调用可观察对象(参见 here。)
如果您在 openFromComponent 函数中这样做,请考虑不要再次调用 .subscribe,而是像这样:
uploadImages() {
// Upload picture and save progress to observable
const uploadProgress: Observable<HttpEvent<HttpUploadProgressEvent>> = this.pictureService.upload(this.selectedFiles);
// Create snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
data: {
uploadProgress.pipe(tap((event: HttpUploadProgressEvent) => {
if (event.loaded === event.total && event.loaded !== undefined) {
this.selectedFiles = null;
this.previewUrls = [];
}
}))
}
})
}
正如 Martin 所建议的,我在常量末尾添加了 .pipe(share())
,现在它可以正常工作了。
我的代码现在看起来像这样:
uploadImages() {
// Upload picture and save progress to observable
const uploadProgress = this.pictureService.upload(this.selectedFiles).pipe(share());
// Create snackbar with observable for progress bar
this.snackBar.openFromComponent(UploadProgressComponent, {
data: { uploadProgress },
});
// Wait for uploading to be finished and then clear selected files and preview URLs
uploadProgress.subscribe((event: HttpUploadProgressEvent) => {
if (event.loaded === event.total && event.loaded !== undefined) {
this.selectedFiles = null;
this.previewUrls = [];
}
});
}