Typescript getCurrent位置并传递到后端以获取结果并传递到材料表数据源 [英] Typescript getCurrent location and pass to backend to get the result and pass to Material Table data source
问题描述
我有一个Angular 2项目,试图获取用户的当前位置,因此在我的课堂上,我有以下代码:
I have my Angular 2 project that tries to get user's current location, therefore in my class I have the following code:
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;
}
}
但是 lat
和 lon
返回 undefined
..我想要的预期行为是一旦获得了这些经度和纬度,就将其发送给我.到我的后端地址,例如以下网址 http://localhost:8080/api/search/location?lat = 123& lon = 123
But lat
and lon
return undefined
.. The expected behaviour I want is once I got those latitude and longitude, I will send it to my backend address like following url http://localhost:8080/api/search/location?lat=123&lon=123
但是似乎为 lat
和 lon
设置值失败.
But it seems like setting value for lat
and lon
are failed.
如何在此类中正确设置纬度和经度?
How can I properly set the latitude and longitude in this class?
在8月3日进行
根据下面的libertyernie的回答,我可以成功地将当前的经纬度传递到后端,但是我不知道如何转换为Observable,因为我尝试在Angular Material中使用Table模块,在该模块中获取数据源必须是可观察的...
According libertyernie's answer below, I can successfully pass the current lat and lon into backend, but I don't know how to convert to Observable, since I try to using Table module in Angular Material, in that module for data source it must be Observable...
这是我尝试后的代码,但仍然无法正常工作...
Here is the code after I try, but still not working...
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() { }
}
抱歉,代码有点混乱..但是我不知道如何将结果传递到 connect()
函数中,以使Material Table起作用..
Sorry about the code is a little bit confusing.. But I don't know how to pass the result into connect()
function to make Material Table works..
也在Github中提供完整代码: https://github.com/zhengye1/Eatr/tree/dev
Full code also in Github: https://github.com/zhengye1/Eatr/tree/dev
推荐答案
getCurrentLocation()中的所有代码将在给予navigator.geolocation.getCurrentPosition的回调有机会运行之前运行.您可以通过在回调中放置另一个console.log语句来查看此情况:
All of the code in getCurrentLocation() will run before the callback given to navigator.geolocation.getCurrentPosition has a chance to run. You can see this by putting another console.log statement inside the callback:
navigator.geolocation.getCurrentPosition((position) => {
console.log("Got position", position.coords);
this.lat = position.coords.latitude;
this.lon = position.coords.longitude;
});
getCurrentPosition需要使用回调的原因有两个:
There are a couple of reasons that getCurrentPosition needs to use a callback:
- 查找地理位置可能需要浏览器查询一些在线服务以找出您的位置
- 可能会提示用户是否要与网站共享位置(这是大多数浏览器的默认行为)
该解决方案可能涉及对getCurrentPosition进行包装,以使其返回promise.我不知道Angular 2可观察对象的工作原理,因此在这一部分我将无济于事,但是您可以让getPosition返回这样的承诺:
The solution probably involves making a wrapper around getCurrentPosition so that it returns a promise. I don't know how Angular 2 observables work so I won't be able to help much in that part, but you could have getPosition return a promise like so:
getPosition = () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition((position) => {
resolve(position.coords);
}, (err) => {
reject(err);
});
});
也许getCurrentLocation可能看起来像这样(只是猜测):
And maybe getCurrentLocation could look like this (just guessing):
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();
}
这篇关于Typescript getCurrent位置并传递到后端以获取结果并传递到材料表数据源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!