如何在Angular中对对象的多个数组属性进行多次http调用?

时间:2017-05-08 20:29:12

标签: angular rxjs reactive-programming observable

我正在学习Angular,而我仍然试图围绕着可观察者。

在我的应用程序中,我进行API调用,返回一个Project对象,该对象具有(在其他属性中)一个对象数组属性,名为" folders"和一个名为"照片的对象数组属性。"每张照片都有一个名为" referenceImageUrl"和一个名为" capturedImageUrl"每个都包含互联网上图像的URL。

我想要做的是下载项目后,下载所有参考图像及其包含的捕获图像。我已经找到了如何下载项目和(我认为)如何为其中一个图像类型的每个图像进行https调用。我无法弄清楚的是如何为每个图像制作两个单独的http调用,以及如何分别循环下载项目的文件夹和图像。

这是我到目前为止的非功能性代码:

return this.http.get(getProjectUrl, { headers: headers })
  .timeout(30000)
  .map(this.extractProjectData)
  .do(project => {
    return this.projectRepository.saveProject(project);
  })
  .mergeMap(project => { return Observable.from(project.photos) })
  .mergeMap(photo => {

      //Download each photo and save the photo to the database
      // (returns an Observable<Photo>)
      return this.photoService.downloadCapturedPhoto(photo);

      //QUESTION: How can I also download the reference photos
      //          using this.this.photoService.downloadReferencePhoto(photo)?

  })
  .mergeMap(project => {

    //QUESTION: How can I get back to working with the project 
                here so I can loop folders, assuming that 
                matrixItemService.downloadCapturedPhoto() does not 
                return the project object
  })
  .catch(this.handleErrors);

修改

在做了一些阅读并查看Martin发布的有用食谱链接后,我现在想出了这个:

return this.http.get(getProjectUrl, { headers: headers })
  .map(this.extractProjectData)
  .do(project => {
    downloadedProject = project;
    return this.projectRepository.saveProject(project);
  })
  .mergeMap(project => { return Observable.from(project.photos) })
  .mergeMap(photo => {
      //Download each photo and save the photo to the database
          return this.photoService.downloadReferencePhoto(photo)
                 .concatMap(photoWithReferenceImage => { return this.photoService.downloadCapturedPhoto(photoWithReferenceImage); })
                 .concatMap(photoWithBothImages => { return this.matrixItemRepository.savePhoto(photoWithBothImages); });
      })
  .mergeMap(project => {
    //QUESTION: How can I get back to working with the project 
            here so I can loop folders
  })
  .catch(this.handleErrors);

我仍然无法理解如何&#34;回归&#34;在下载照片后使用该项目,以便我可以使用其文件夹。

2 个答案:

答案 0 :(得分:2)

好的,我想出来了。我没有理解的关键概念是,我可以像任何其他函数一样声明引用可观察对象和主题的变量,并且我可以直接从数组声明一个新的可观察流。

这是我的问题的解决方案:下载一个项目,然后声明两个单独的可观察文件,用于保存文件夹并下载和保存参考图像。然后forkJoins这两个observable并返回结果observable,这样一旦调用代码订阅了外部observable,两个流都会运行。

return this.authHttp.get(getProjectUrl, { headers: headers })
      .timeout(30000)
      .map(this.extractProjectData)
      .do(extractedProject => {
        return this.projectRepository.saveProject(extractedProject)
        .then(() => { project = extractedProject; });
  })
  .mergeMap(() => {

    totalPhotoCount = project.photos.length;

    let folderWork = Observable.from(project.folders)
      .concatMap((folder: Folder) => {
        return this.matrixItemService.saveFolder(folder);
      });

    let photoWork = Observable.from(project.photos)
      .mergeMap((photo: Photo) => {
        return this.matrixItemService.saveProjectPhoto(photo)
          .then(() => {
            ++completedPhotoCount;
            this.minorProgressSource.next(`Downloading photo ${completedPhotoCount} of ${totalPhotoCount}`);
          });
      }, undefined, 3); //3 = concurrent downloads and saves

    return Observable.forkJoin(folderWork, photoWork);


  })
  .catch(this.handleErrors);

答案 1 :(得分:-3)

我不知道Angular 2,但是如果你想一次发出多个http调用,那么在最新的JQuery中有一个新的$ .when,请查看它?