2016-07-07 6 views
1

관찰 가능한 구독 체인으로 인해 발생하는 데이터에서 작동하는 함수를 실행해야하지만 내 개체 생성이 완료된 후에야합니다. 당신이 볼 수 있듯이, 나는 모든이 있다고 그런 후 ... 등 그 결과 각에서 다른, getCamps에서 반환 된 각 항목에서 구독을 만들 필요가 있고,관찰 가능한 구독 체인이 완료된 후 함수 실행 (각도 2)

getFilters() { 
     this.filterSvc.getCamps() 
      .subscribe(
       c => { 
        this.filters = c; 
        for (let camp of this.filters) { 
         this.filterSvc.getBuildings(camp.id) 
          .subscribe(
           b => { 
            camp.buildings = b; 
            for (let building of camp.buildings) { 
             this.filterSvc.getFloors(building.id) 
              .subscribe(f => { 
               building.floors = f 
              }); 
            }; 
           }); 
        } 
       }); 
      // ONLY DO THIS AFTER THE OBJECT IS HYDRATED 
      this.globals.setCampFilters(this.filters); 
    } 

: 여기

내 체인의 완료에, 나는 실행하려는 내 필터를 채우는 가기 전에 내 모든 캠프 건물을 가지고 있고 모든 건물 바닥이 때까지 기다릴 수있는 방법

setCampFilters(this.filters); 

?

답변

1

나는 Object.forJoin과 함께 flatMap 연산자를 사용합니다. 다음은 샘플입니다.

getFilters() { 
    this.filterSvc.getCamps() 
     .flatMap(c => { 
      this.filters = c; 
      // Observables for all camps 
      return Observable.forkJoin(this.filters.map(camp => { 
      // Links camp with the result of getBuildings 
      return Observable.forkJoin([ 
       Observable.of(camp), 
       this.filterSvc.getBuildings(camp.id) 
      ]); 
      }) 
     }) 
     .map(results => { 
      // Map results and link buildings with camps 
      return results.map(result => { 
      let camp = result[0]; 
      let buildings = result[1]; 
      camp.buildings = buildings; 
      return camp; 
      }); 
     }) 
     .subscribe(camps => { 
      // ... 
     ]); 

flatMap 연산자를 연결할 수 있습니다.

이 문서에서는 관심 수 :

+0

여기에 뭔가있는 것처럼 보이지만 구현이 실행될 때 내부 코드의 많은 부분에 도달하지 못하는 것처럼 보인다. 심지어 어지럽게되고 중단 점을 설정 한 후에도 대부분이 충돌하지 않고 오류가 발생하지 않으며 궁극적으로 제 필터가 채워지지 않습니다. 존경심으로, 귀하의 블로그 게시물에 대한 클릭 유도를 단순히 시딩했는지 또는 실제로 문제를 생각했는지 궁금합니다. – Methodician

1
window.getFilters = function() { 
    this.filterSvc.getCamps() 
    .do((c: any) => this.filters = c) 
    .flatMap((c: any) => Observable.from(c)) // convert from Observable<Array<Camp>> to Observable<Camp> 
    .flatMap((camp: any) => this.filterSvc.getBuildings(camp.id).do(b => camp.buildings = b)) 
    .flatMap(b => Observable.from(b)) 
    .flatMap((building: any) => this.filterSvc.getFloors(building.id).do(f => building.floors = f)) 
    .subscribe(null, null,() => this.globals.setCampFilters(this.filters)); 
} 

이 flatMap의 일련의 관찰 가능한 < 배열 < 바닥에 >> 관찰 가능한 < 배열 < 캠프에서 관찰을 설정 >> 그리고 그것의 onComplete 이벤트에 this.globals.setCampFilters으로 전화하면됩니다.

편집 : Typescript 컴파일러가 호환되지 않는 형식에 대해 불평하지 않도록 코드를 업데이트했습니다. 나는을 추가한다. TS 컴파일러가 불평 할 것이라고 생각한다. 전에 을 추가 할 수있다. =>

+0

당신의 대답은 유망한 것처럼 보이지만 " 'id'속성은 '{}'유형에 존재하지 않으며 'property'buildings '는'{} '유형에 존재하지 않으며 해킹 할 수 없습니다 TS에 c가 "MenuCamp"유형이고 건물이 "MenuBuilding"등의 유형임을 TS에 알리는 좋은 방법 ... – Methodician

+0

TS를 사용하는 경우'c =>','camp =>'을 바꿀 수 있습니다. .. (c : any) =>','(camp : any) =>'. 원한다면 코드가 성공적으로 컴파일 된 후에 해당 형식으로'any'를 대체하려고 할 수 있습니다. (그러나 필자는 생각하지 않습니다.) –

+0

그리고 다음에'# typescript' 태그를 추가하십시오. TS 또는 ES6/7을 사용하고 있다면 코드에서 알기가 어렵습니다. –

관련 문제