2017-05-08 2 views
0

Ich lerne Angular und versuche immer noch, mich mit Observablen zu beschäftigen.Wie kann ich mehrere HTTP-Aufrufe für mehrere Array-Eigenschaften eines Objekts in Angular vornehmen?

In meinem app Ich mache einen API-Aufruf, die ein Projekt-Objekt zurückgibt, die (unter anderen Eigenschaften) eine Objekt-Array-Eigenschaft namens „Ordner“ und eine Objekt-Array-Eigenschaft genannt hat „Fotos“. Jedes Foto hat seinerseits eine Eigenschaft namens "referenceImageUrl" und eine namens "capturedImageUrl", von denen jede eine URL zu einem Bild im Internet enthält.

Was ich tun möchte, ist nach dem Projekt herunterladen, laden Sie die alle Referenzbilder und die aufgenommenen Bilder enthält. Ich habe herausgefunden, wie man das Projekt herunterlädt und (wie ich denke) dann https Aufrufe für jedes Bild für einen der Bildtypen macht. Was ich nicht herausfinden kann, ist, wie man zwei separate http-Aufrufe für jedes Bild macht, und auch, wie man die Ordner und Bilder des heruntergeladenen Projekts getrennt durchläuft.

ist der nicht-funktionale Code, den ich bisher habe:

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); 

Edit:

Nach etwas mehr lesen und mit Blick auf den hilfreichen Rezepte tun verknüpfen, dass Martin geschrieben, ich habe jetzt mit diesem kam:

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); 

ich kann immer noch nicht verstehen, wie man „zurück“ mit dem Projekt nach den Fotos zu arbeiten dow nload, damit ich dann mit seinen Ordnern arbeiten kann.

+0

http://stackoverflow.com/documentation/rxjs/8247/common-recipes/27973/sending-multiple-parallel-http-requests#t=201705082301056342059 – martin

Antwort

2

OK, das habe ich herausgefunden. Das Schlüsselkonzept, das ich nicht begriff, war, dass ich Variablen deklarieren kann, die wie jede andere Funktion auf Observablen und Subjekte verweisen, und dass ich einen neuen beobachtbaren Stream direkt von einem Array aus deklarieren könnte.

Hier ist meine Arbeitslösung zu meiner Frage: dies ein Projekt herunterlädt, erklärt dann zwei separate Observablen, die Ordner und speichern herunterladen und Referenzbilder speichern. Es verzweigt dann diese beiden Observablen und gibt die resultierende Observable zurück, so dass beide Ströme laufen, sobald der aufrufende Code die äußere beobachtbare Subskription abschließt.

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

Ich weiß nicht, Angular 2, aber wenn Sie mehrere http machen möchten Anrufe auf einmal, neu ist es ein .when $ im letzten JQuery, check it out?

Verwandte Themen