2017-08-07 70 views
0

我試圖將從http請求獲得的值推送到本地聲明變量userLat & userLng,並從另一個函數訪問變量,但得到的結果爲undefineduserLat & userLng已成功檢索。嘗試使用return this.userLat & this.userLng但失敗,請指出我是否犯了錯誤。如何將函數的值傳遞給函數?

以前使用承諾工作。有很多頭痛。有沒有更簡單的方法來獲取數據?

任何幫助和建議表示讚賞。感謝提前:)

map.ts

export class GoogleMapsProvider { 

userLat:any; 
userLng:any; 

constructor(
public http: Http, 
) { 
} 

load(){ 
    this.http.post() 
    .map(res => res.json()) 
    .subscribe(data => 
    { 
     this.userDetails = data[0]; 

     this.userLat = this.userDetails.ListerLat; 
     this.userLng = this.userDetails.ListerLng; 

     console.log(this.userLat); // successfully return userLat 
     console.log(this.userLng); // successfully return userLng 

    //tried return this.userLat & this.userLng 

    } 
} 


calculate(locations) { 

    console.log(this.userLat); //returned undefined 
    console.log(this.userLng); //returned undefined 

    let usersLocation = { 
    lat: this.userLat, 
    lng: this.userLng 
}; 

} 

使用承諾

load(){ 

    if(this.data){ 
     return Promise.resolve(this.data); 
    } 

    return new Promise(resolve => { 

     this.http.get('../example.json').map(res => res.json()).subscribe(data => { 

this.data = data; 

      resolve(this.data); 
     }); 

    }); 

} 
+2

你怎麼叫'calculate'功能? – MysterX

+0

好的。對於那個很抱歉。將來會注意到。 我在另一個函數中調用'calculate'函數。以前我使用硬編碼'userLat&userLng',它工作正常。現在我想將其應用於動態數據。 – aaa

+1

這對我來說似乎是一個範圍問題,您應該使用let _self = this;在你的加載方法中。然後通過_self.userLng = value設置userLng; – user3492940

回答

3

,你可以在這裏做什麼是創建一個包含經度和緯度可觀察到的數據流,並訂閱在你的計算函數中。這意味着你永遠不會在業務邏輯中調用calculate,當你的服務被實例化時,你只會調用它一次。

任何時候數據從load方法回來,你的calculate邏輯將被觸發。你可以相信,當你從你的服務器得到響應時,這總是會發生,你不必自己管理計算調用。

那麼幾件事情:

  • 從服務中刪除經/緯度性能。
  • 創建一個可觀察數據流將包含兩個值(經/緯度)
  • 立即訂閱該流,那麼你load功能增加值到流的任何時間,計算將完成。

您的服務可以是這樣的:

import { ReplaySubject } from 'rxjs/ReplaySubject'; 

export interface Location { 
    latitude: number; 
    longitude: number; 
} 

export class GoogleMapsProvider { 
    private locationStream: ReplaySubject<Location> = new ReplaySubject(); 

    constructor(public http: Http) { 
     // Subscribes to the location observable stream. 
     this.calculate(); 
    } 

    load(){ 
     this.http.post() 
      .map(res => res.json()) 
      .subscribe(data => { 
       this.userDetails = data[0]; 

       // This will add the location values to the stream. 
       this.locationStream.next({ 
        latitude: this.userDetails.ListerLat, 
        longitude: this.userDetails.ListerLon 
       }); 
      }); 
    } 


    calculate() { 
     // Any time the `load` adds values to the stream, the subscribe callback will be triggered. 
     this.locationStream.asObservable().subscribe((location: Location) => { 
      // Do some calculations using location.latitude and location.longitude 
     }); 
    } 
} 

如果你不喜歡用觀察到的數據流的方法,你仍然可以使你的calculate功能純做到這一點。的

所以不是訪問this.userLatthis.userLon,你的位置對象傳遞,以便計算功能變爲純粹的斷其輸入 - 這樣就不會有未定義的值,如果你確保你只能叫calculate與定義的值。

但是,這種方法的唯一問題是您不能從load方法的外部調用calculate而不使calculate方法成爲不純的函數。而且我建議不要試圖在服務中保持userLatuserLon屬性的狀態,因爲隨着複雜性的增長,這可能很難調試。

然而,在這裏你去:

export interface Location { 
    latitude: number; 
    longitude: number; 
} 

export class GoogleMapsProvider { 
    constructor(public http: Http) {} 

    load() { 
     this.http.post() 
      .map(res => res.json()) 
      .subscribe(data => { 
       this.userDetails = data[0]; 

       // Call `calculate` here and pass in location object. 
       this.calculate({ 
        latitude: this.userDetails.ListerLat, 
        longitude: this.userDetails.ListerLon 
       }); 
      }); 
    } 


    calculate(location: Location) { 
     // Do calculations with location.latitude and location.longitude 
    } 
}