2017-01-23 63 views
0

我有以下服務類,其被在提供商等設定爲單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)的對象,因爲它應該在一個輸出未定義之後,不應該由它設置?使事情變得更糟。

我呼籲構造和在我的網頁上loadappdata我想通過調用

export class HomePage { 

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


} 

獲取對象,但getAppData總是不確定的,

我想有一個服務保留的對象所以我的網頁可以根據需要從中獲取數據。我的印象是,這應該如何利用服務跨頁面共享數據

回答

0

由於http.get調用的異步ajax請求,您正面臨這些問題。在this.loadAppData功能PROGRAMM順序如下:首先 你做this.http.get

接下來CONSOLE.LOG外的Ajax請求訂閱

一旦GET請求的響應接收響應訂閱的箭頭函數將被調用,並且您再次調用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,加載數據,你在我的第一個例子的主頁中,並在訂閱成功函數分配數據到一個TestService成員變量,您可以訪問每個頁面,然後分配rootPage。 – LuJaks

0

1 - 您可以使用NGRX店https://github.com/ngrx/store - 存儲服務結果和每一頁都將取回保存的信息。

2-使用ReplaySubject -

在服務代碼:

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(); 
    } 

在您的主頁:

export class HomePage { 

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

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

}

在您的個人資料頁面

export class ProfilePage { 

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

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

不能我只是存儲我回來的對象在全球比不得不使用商店?似乎效率不高,必須稍後存儲和檢索。 – Zoinky