2017-01-23 2 views
0

Iは、以下のサービス・クラス、それは等プロバイダにシングルトンとして設定されているionic2サービスデータrention

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { Geolocation } from 'ionic-native'; 
import { Platform } from 'ionic-angular'; 

import 'rxjs/Rx'; 

@Injectable() 
export class TestService { 
private appData: any; 
constructor(private http: Http) { 
    console.log("service constructor called"); 
    this.loadAppData(); 
} 

loadAppData() { 
    let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
    this.http.get(url).map(res => res.json()).subscribe(data => { 
     this.appData = data; 
     console.log(this.appData); 
    }); 
    console.log(this.appData); 
} 
getAppData() 
{ 
    return this.appData; 
} 

} 

加入出力内部にconsole.log(this.appData)それが1べきオブジェクトとして出力が定義されていない場合、それまでに設定してはいけませんか?事態を悪化させる。私は、オブジェクトを保持してサービスを持ってしようとしています

、私はコンストラクタで、私のページでloadappdataを呼び出しています

iは

export class HomePage { 

constructor(public navCtrl: NavController, public testService: TestService) { 
console.log(testService.getAppData()); 
}; 


} 

を呼び出すことにより、オブジェクトを取得したいが、getappdataを、常に定義されていません私のページは必要に応じてデータを取得できます。私は、ページ全体でデータを共有するためにサービスをどのように利用すべきかという印象を受けました

答えて

0

http.get呼び出しの非同期のajax要求のために、これらの問題に直面しています。次のようにthis.loadAppData機能でプログラムの開発順序は次のとおりです。 まず、あなたがget要求の応答は、応答を受信すると

次はあなたが購読

外CONSOLE.LOG this.http.get AJAX要求を行いますsubscribeのarrow関数が呼び出され、console.logが再び呼び出されます。

解決策は、サービスからhttp.get Observableを返し、コンポーネント内でそれを購読することです。

@Injectable() 
export class TestService { 
constructor(private http: Http) {} 

loadAppData() { 
    let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
    return this.http.get(url).map(res => res.json()); 
} 


export class HomePage { 
    constructor(public navCtrl: NavController, public testService: TestService) { 
     this.testService.loadAppData().subscribe(data => { 
      this.appData = data; 
     }); 
    }; 
} 

データをキャッシュするには、プロキシをローカルにキャッシュされたデータに解決するか、利用可能なリクエストと返品がない場合に返すことができます。たとえば、次のように

@Injectable() 
export class TestService { 

    public data: any; 

    constructor(private http: Http) {} 

    loadAppData() { 

     return new Promise((resolve) => { 
      if (this.data) { 
       return resolve(this.data); 
      } else { 
       let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
       return this.http.get(url) 
        .map(res => res.json()) 
        .subscribe(data => { 
         this.data = data; 
         return resolve(data); 
        }); 
      } 
     }); 
} 
+0

しかし、複数のページからloadAppDataを複数呼び出しても、URLを複数回呼び出すことはありませんか?私はloadAppDataを一度呼び出すと、その結果を何度も何度も呼び出しなくても使用しようとしています – Zoinky

+0

私はいくつかのコードを追加しました。欠点は、データを再読み込みするタイミングを制御できないことです。 代わりに、あなたのapp.componentに、私の最初の例のHomePageでデータを読み込んで、購読の成功関数ですべてのページでアクセスしたTestServiceメンバー変数にデータを割り当て、次にrootPageを割り当てます。 – LuJaks

0

1 - サービスの結果を保存するために、各ページは、ストアから情報を取得します - あなたはngrx店https://github.com/ngrx/storeを使用することができます。プロフィールページで

export class HomePage { 

constructor(public navCtrl: NavController, public testService: TestService) { 
console.log(testService.getAppData()); 
}; 

ngOninit() { 
this.appData.subscribe(resp => { 
console.log(resp) 
}); 

}

あなたのホームページで

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { Geolocation } from 'ionic-native'; 
import { Platform } from 'ionic-angular'; 

import 'rxjs/Rx'; 

@Injectable() 
export class TestService { 
private appData: any; 
constructor(private http: Http) { 
    this.userSubject = new ReplaySubject<any>(1); 
this.loadAppData().subscribe(resp => {console.log(resp)}); 
} 

loadAppData():observable<any> { 
    let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
    this.http.get(url).map(res => res.json()).map(data => { 
     this.userSubject.next(data); 
     return data; 
    }); 
    console.log(this.appData); 
} 

get appData(): Observable<any> { 
    return this.userSubject.asObservable(); 
    } 

:あなたのサービスコードで

-

2 - 使用ReplaySubject

export class ProfilePage { 

    constructor(public navCtrl: NavController, public testService: TestService) { 
    console.log(testService.getAppData()); 
    }; 

    ngOninit() { 
    this.appData.subscribe(resp => { 
    console.log(resp) 
    }); 
} 
+0

カント私はちょうど店を使用することよりもグローバルに戻って取得するオブジェクトを格納する?後で瞬間を保存して検索するのが効率的ではないようです。 – Zoinky