web-dev-qa-db-ja.com

Angular 4

私は、Angular 4を使用して、映画の上映時間を表示するHttpClientを使用したアプリケーションを作成しています。データが配置されているJSONファイルは2つあります:showtimes.jsonおよびmovies.json

// showtimes.json    
[{
"id": "2030c64ce72b4e4605cb01f2ba405b7d",
"name": "Arclight", // need to display this information
"showtimes": {
  "b4c2c326a4d335da654d4fd944bf88d0": [ // need to use this id
      "11:30 pm", "2:45 pm", "8:35 pm", "4:15 pm", "10:30 pm"
  ]
 } 
}]

// movies.json
[{
"b4c2c326a4d335da654d4fd944bf88d0": { // to retrieve the title, rating, and poster
  "title": "Fifty Shades Darker", // needs to be displayed
  "rating": "R", // needs to be displayed
  "poster": "https://dl.dropboxusercontent.com/s/dt6wgt92cu9wqcr/fifty_shades_darker.jpg" // needs to be displayed
}
}]

劇場のtitlenameを取得できるサービスがあります。ただし、正しいタイトル名を表示するには、showtimesオブジェクトの値を使用する必要があります。ご覧のとおり、b4c2c326a4d335da654d4fd944bf88d0は映画のタイトルのIDであり、movies.jsonファイルから取得できます。

これまでのところ、これは私のコンポーネントです

ngOnInit() {
  this._moviesDataService.getShowtimes()
  .subscribe(res => this.results = res)
}

そして、これは私のサービスです。

getShowtimes (): Observable<ShowTimes> {
  return this._http.get<ShowTimes>(this._showtimesURL)
}

私の質問は、IDを使用して映画のtitleを取得するにはどうすればよいですか?これには2つのチェーンされたObservableが必要ですか? movies配列をループして.filterする必要がありますか?

私が構築しようとしているものの例を含めました Example

8
Kim Merino

通常、Observableが1つあり、から何かを取得する必要がある場合。それと別のObservableを返す場合は、switchMapを使用できます。

ngOnInit() {
    this._moviesDataService.getShowtimes()
        .switchMap(res => { 
            const id = Object.keys(res[0].showtimes)[0]; // assuming you have one element in your array and you want the first id from showtimes
            return this.getMovies(id); // assuming, you have a separate method that returns the movies
        })
        .subscribe(res => this.results = res)
}

[〜#〜]更新[〜#〜]

両方のObservableの結果が必要なだけでなく、最初の結果も2番目に要求する必要があるので、次の方法でこれを行うことができます。

ngOnInit() {
    this._moviesDataService.getShowtimes()
        .switchMap(res => { 
            const showtimes = res[0].showtimes;
            const id = Object.keys(showtimes)[0];

            return Observable.Zip(
                this.getMovies(id),
                Observable.of(showtimes[id])
            );
        })
        .subscribe(([movies, showtimes]) => {
            this.results.movies = movies; // or assign it to some other property
            this.results.showtimes = showtimes; // and use in the template
        }
12
Boris Lobanov

すべての映画のタイトルを取得する必要があるため、最初のリクエストのレスポンスにあるIDの配列を、映画のタイトルの一連のリクエストにチェーンする必要があると思います。このようなもの:(あなたがそれのIDに基づいて映画のデータを取得し、それがオブザーバブルを返すgetMovieTitleのようなメソッドがあると仮定します)

this._moviesDataService.getShowtimes()
        .switchMap(res => { 
            let resArray: any[] = res.map(
                    item=>this._moviesDataService.getMovieTitle(
                        Object.keys(item.showtimes)[0]
            ))
            return Observable.merge(...resArray);
        })
        .subscribe(res => /*you will get a new res for each movie title here*/)

何 - Observable.merge する、それはTurn multiple observables into a single observable.したがって、1つのサブスクリプションですべての結果を取得できます。

注:これをすべてsubscriptionに割り当て、コンポーネントのngOnDestroyで登録解除することを忘れないでください(メモリリークを防ぐため)

0
GHB