打字稿获取当前位置并传递给后端以获取结果并传递给材料表数据源

Vin*_*eng 5 typescript angular

我有我的 Angular 2 项目试图获取用户的当前位置,因此在我的班级中我有以下代码:

export class CurrentLocation {
  constructor(private http: Http) { }
  private lat : any;
  private lon : any;
  private params  = new URLSearchParams();
  private url = 'api/search/location';


  getPosition = (lat, lon) => {
    navigator.geolocation.getCurrentPosition((position) => { 
      this.lat = position.coords.latitude; 
      this.lon = position.coords.longitude;
     });
  }
  getCurrentLocation(): Observable<any> {
    this.getPosition(this.lat, this.lon);
    console.log(this.lat+ "," + this.lon);
    //console.log(this.lat + ":" + this.lon);
    this.params.set('lat', this.lat);
    this.params.set('lon', this.lon);
    //console.log(this.params.toString());
    var result = this.http.get(this.url, { search: this.params });
    result.toPromise();
    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是latlon返回undefined..我想要的预期行为是一旦我获得了这些纬度和经度,我就会将它发送到我的后端地址,如以下网址http://localhost:8080/api/search/location?lat=123&lon=123

但似乎为lat和设置值lon失败。

如何在该类中正确设置纬度和经度?

8月3日编辑:

根据下面的 libernie 的回答,我可以成功地将当前经纬度传递到后端,但我不知道如何转换为 Observable,因为我尝试在 Angular Material 中使用 Table 模块,在该模块中作为数据源它必须是 Observable ...

这是我尝试后的代码,但仍然无法正常工作...

import { Component, OnInit } from '@angular/core';
import { Http, Response, URLSearchParams } from '@angular/http';
import { DataSource } from '@angular/cdk';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import { Restaurant } from '../restaurant/restaurant';
import { Category } from '../category/category';
import { RestaurantService } from '../restaurant/restaurant.service';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  displayedColumns = ['Id', 'Name', 'Category', 'Address', 'City'];
  exampleDatabase: ExampleHttpDatabase | null;
  dataSource: ExampleDataSource | null;
  location: CurrentLocation | null;
  lat: any;
  lon: any;
  result: Promise<any>;

  constructor(http: Http) {
    this.exampleDatabase = new ExampleHttpDatabase(http);
    this.dataSource = new ExampleDataSource(this.exampleDatabase);
    this.location = new CurrentLocation(http);
  }

  ngOnInit() {
    this.result = this.location.getCurrentLocation(this.lat, this.lon);
    this.result.then(function(result){
      console.log(result._body);
    })
    console.log(this.lat, this.lon);
    this.dataSource.connect();
  }
}

export class ExampleHttpDatabase {
  private restaurantUrl = 'api/restaurant'; // URL to web API
  getRestaurants(): Observable<Restaurant[]> {
    var result = this.http.get(this.restaurantUrl)
      .map(this.extractData);
    result.toPromise();
    return result;
  }

  extractData(result: Response): Restaurant[] {
    return result.json().map(restaurant => {
      return {
        id: restaurant.id,
        name: restaurant.restaurant_name,
        category: restaurant.category.map(c => c.categoryName).join(','),
        address: restaurant.address.address,
        city: restaurant.address.city.city_name
      }
    });
  }
  constructor(private http: Http) { }
}

export class CurrentLocation {
  constructor(private http: Http) { }
  private lat: any;
  private lon: any;
  private params = new URLSearchParams();
  private url = 'api/search/location';


  getPosition = () => {
    var latitude, longitude;
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition((position) => {
        resolve(position.coords);
      }, (err) => {
        reject(err);
      });
    })
  }
  async getCurrentLocation(lat, lon): Promise<any> {
    let coords = await this.getPosition();
    lat = this.lat = coords['latitude'];
    lon = this.lon = coords['longitude'];
    this.params.set('lat', this.lat);
    this.params.set('lon', this.lon);
    var result = this.http.get(this.url, { search: this.params });
    return await result.toPromise();
  }
}

export class ExampleDataSource extends DataSource<Restaurant> {
  constructor(private _exampleDatabase: ExampleHttpDatabase) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<Restaurant[]> {
    return this._exampleDatabase.getRestaurants();
  }

  disconnect() { }
}
Run Code Online (Sandbox Code Playgroud)

抱歉代码有点混乱..但我不知道如何将结果传递给connect()函数以使材料表工作..

完整代码也在 Github:https : //github.com/zhengye1/Eatr/tree/dev

lib*_*nie 5

getCurrentLocation() 中的所有代码都将在给 navigator.geolocation.getCurrentPosition 的回调有机会运行之前运行。您可以通过在回调中放置另一个 console.log 语句来查看这一点:

navigator.geolocation.getCurrentPosition((position) => { 
  console.log("Got position", position.coords);
  this.lat = position.coords.latitude; 
  this.lon = position.coords.longitude;
});
Run Code Online (Sandbox Code Playgroud)

getCurrentPosition 需要使用回调有几个原因:

  • 地理定位查找可能需要浏览器查询一些在线服务以找出您的位置
  • 用户可能会收到提示,询问他们是否要与网站共享他们的位置(这是大多数浏览器的默认行为)

解决方案可能涉及围绕 getCurrentPosition 制作一个包装器,以便它返回一个承诺。我不知道 Angular 2 observables 是如何工作的,所以我在这方面帮不上什么忙,但是你可以让 getPosition 返回一个像这样的承诺:

getPosition = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition((position) => { 
      resolve(position.coords);
    }, (err) => {
      reject(err);
    });
  });
Run Code Online (Sandbox Code Playgroud)

也许 getCurrentLocation 看起来像这样(只是猜测):

async getCurrentLocation(): PromiseLike<any> {
  let coords = await this.getPosition(this.lat, this.lon);
this.lat = coords['latitude'];
this.lon = coords['longitude'];
  this.params.set('lat', this.lat);
  this.params.set('lon', this.lon);
  var result = this.http.get(this.url, { search: this.params });
  return await result.toPromise();
}
Run Code Online (Sandbox Code Playgroud)