2017-02-12 5 views
0

データ(ジム配列)を一度ロードしたサービスを実装してから、他のすべてのコンポーネントが他のHTTPリクエスト。Angular2 - サービスがデータの取得を完了するまでコンポーネントを待機させてからレンダリングします

ユーザーがタイトルページから開始してすべてのデータを読み込んだ場合、アプリケーションが正常に動作しますが、特定の詳細ページ(.../gym/1)に移動してページをリロードすると、オブジェクトはまだサービス配列内にありません。データがロードされるまで、サービス配列にアクセスしようとするコンポーネントを待たせる方法を教えてください。具体的には、どのようにgetAllGymsFromBackEnd()関数が配列を取り込むまで、GymComponentのgymService.getGym(1)の呼び出しを遅延させることができますか?

私はリゾルバーについて読んだことがありましたが、私の悩みは私をどこにも導きませんでした。

ご協力いただければ幸いです。

これは、私が働いていたコードです:

サービス:

import {Injectable} from "@angular/core"; 
import {Gym} from "../objects/gym"; 
import {BaseService} from "./base.service"; 
import {Http, Response} from "@angular/http"; 
import {HttpConstants} from "../utility/http.constants"; 

@Injectable() 
export class GymService extends BaseService { 

    private gyms: Gym[] = []; 

    constructor(protected http: Http, protected httpConstants: HttpConstants) { 
     super(http, httpConstants); 
     this.getAllGymsFromBackEnd(); 
    } 

    getAllGymsFromBackEnd() { 
     return super.get(this.httpConstants.gymsUrl).subscribe(
     (data: Response) => { 
      for (let gymObject of data['gyms']) { 
       this.gyms.push(<Gym>gymObject); 
      } 
     } 
    ); 
    } 

    getGyms() { 
     return this.gyms; 
    } 

    getGym(id: number) { 
     return this.gyms.find(
     gym => gym.id === id 
    ) 
    } 
} 

コンポーネント:

import {Component, OnDestroy, AfterViewInit, OnInit} from "@angular/core"; 
import {ActivatedRoute} from "@angular/router"; 
import {Subscription} from "rxjs"; 
import {Gym} from "../../objects/gym"; 
import {GymService} from "../../services/gym.service"; 
declare var $:any; 

@Component({ 
    selector: 'app-gym', 
    templateUrl: './gym.component.html', 
    styleUrls: ['./gym.component.css'] 
}) 
export class GymComponent implements OnInit, OnDestroy, AfterViewInit { 

    private subscription: Subscription; 
    private gym: Gym; 

    constructor(private activatedRoute: ActivatedRoute, 
      private gymService: GymService 
    ) {} 

    ngOnInit(): void { 
     this.subscription = this.activatedRoute.params.subscribe(
     (param: any) => { 
      this.gym = this.gymService.getGym(parseInt(param['id'])); 
     } 
    ); 
    } 

    ngAfterViewInit(): void { 
     $(document).ready(function() { 
     $('.carousel').carousel(); 
     }); 
    } 

    ngOnDestroy(): void { 
     this.subscription.unsubscribe(); 
    } 
} 
+0

あなたのサービスは、*購読可能な観測可能性を公開する必要があります。例えば、 'ReplaySubject'を使ってキャッシュとして動作させることができます。 'getGyms'を' Observable 'に戻します。 – jonrsharpe

+0

返事をありがとう、私はあなたが提案したように変更を加えました。私はそれを正しくしたかどうか見てみることができますか?また、getGym(id)関数を実装してコンポーネントで使用する方法もわかりませんが、そのようにも助けてください。 – Vodyara

+0

質問が回答を得た後に変更しないでください。あなたが正しいことをしたかどうかを知りたければ、それをテストしてください! – jonrsharpe

答えて

1

あなたにもResolverを使用することができます。ここで確認してくださいhttps://angular.io/docs/ts/latest/api/router/index/Resolve-interface.htmlまたはObservableを使用してください。したがってprivate gym: Gym;private gym$:Observable<Gym>;になり、テンプレートではasyncパイプを使用してデータを取得します。

+0

https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard –

+0

こちらもお読みください。 – Vodyara

関連する問題