2016-10-28 3 views
1

다음과 같은 구성 요소가 Angular2에 있습니다. 배열을 입력으로 받아서 서비스 호출을 통해 배열의 각 항목에 대해 각 항목의 위도와 경도를 (약속을 반환) 서비스ngIf가 템플릿을 업데이트하지 않습니다.

export class MyComponent implements OnInit { 

    @Input() players: Player[] = []; 
    locations: LatAndLon[] = []; 
    isBusy: boolean = true; 


    constructor(
     private myService: MyService, 
    ) {} 

    ngOnInit(): void { 
     for (let player of this.players) { 
      this.myService.getLatAndLon(player.address).then(latAndLon => { 
       this.locations.push(latAndLon); 
       this.finishLoading(); 
      }); 
     } 

    } 

    finishLoading(): void { 
     this.isBusy = this.players.length != this.locations.length; 
    } 
    ... 
} 

그래서, ngOnInit 방법에 내 서비스에서 모든 데이터를 얻을하려고합니다. 그런 다음 템플릿에 표시하고 싶지만 모든 서비스 호출을 "해결"할 때까지 기다려야합니다.

그 때문에 모든 데이터를 사용할 수 있는지 확인하는 변수 isBusy을 만들었습니다. 나는 isBusy을 서비스에 전화 할 때마다 업데이트하려고합니다. 어쩌면 당신은 다른 접근법을 가지고 있습니다. 그렇다면 알려주세요.

<div *ngIf="!isBusy"> 
.... 

그러나이 아무것도 표시되지 않습니다, 나는 위치 배열의 값을 인쇄하는 경우, 내가 모든 것을 잘 모른다는 단서를 볼 수 있다는 사실에도 불구하고 :

그런 다음, 나는 다음과 같은 템플릿이?

+0

요청 중 하나가 실패하면 아무 것도 표시되지 않습니다. 어쩌면 그렇게 될지도 모릅니다. 'isBusy'를 출력하면 예상대로 설정됩니까? –

+0

안녕하세요, 나는 그것을 검사하고 모든 요청이 좋다, 그리고 isBusy는 false로 끝에 설정됩니다. – Manuelarte

+0

문제를 재현하는 완벽한 예제를 plunkr에 게시하십시오. 약속은 좋은 순서로 해결된다는 보장이 없기 때문에 코드는 당신이 원하는 것을하지 않을 것입니다. Promise.all()을 사용하거나 플레이어 자체에서 LatLon을 스트로크해야합니다. –

답변

1

당신이 관찰 스트림으로 입력 배열을 변환하면 쉽게 할 수있다 :

ngOnInit() { 
    let source = Observable.from(this.players) 
    .concatMap(x => Observable.fromPromise(this.myService.getLatAndLon(x))); 

    let subscription = source.subscribe(
    x => this.locations.push(x), 
    error => console.log('Error ', error), 
    () => this.isBusy = false 
); 
} 

참고 : 사용 concatMap를 당신이 당신의 입력 배열의 순서를 유지하기 위해 위치 배열이 필요합니다. 필요하지 않은 경우 flatMap을 사용할 수 있습니다.

여기 Observable 인과 약속을 브리징에 대한 문서입니다 :

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/promises.md

도움이 되었기를 바랍니다.

관련 문제