我想在地图上放置标记。源是一个json请求,它返回城市。
我有一个函数(sencha)返回记录(异步)和一个函数(google maps api),它返回特定城市的lng,lat(异步)和一个放置标记的方法(google maps)在地图上。
结果应该是谷歌计算出的位置地图上的标记,并从记录中检索到标题。
加载记录
offers = App.stores.offers.load({
callback: function(records, operation, success){...}
})
获取位置
geocoder = new google.maps.Geocoder();
geocoder.geocode(
{'address': adress},
function(results, status) {...}
}
并设置标记
marker = new google.maps.Marker({
map: map,
position: loc,
title: text
});
我不想做的是,加载记录,循环遍历每条记录,找出城市的位置并在那里放置标记。
同步我会这样做:
records = App.stores.offers.load();
for (var i=0; i < records.length; i++) {
setMarker( map, getLocation(records[i].data["city"]), cords[i].data["text"]);
}
将异步函数与它结合在一起的正确方法是什么?
答案 0 :(得分:0)
我真的不知道App.stores.offers.load函数究竟做了什么,但我假设它的回调函数参数包含记录变量中的加载结果。在这种情况下,循环遍历回调函数内的记录和每个调用地理编码,以及地理编码的回调位置标记(没有错误)。
编辑:这是未经测试的,可能效率不高但应该有效:
offers = App.stores.offers.load({
callback: function(records, operation, success){
if (success) {//or sth like this
var complete;
for (var i = 0; i < records.length; i++) {
complete = false;
geocoder.geocode( {'address': records[i].adress},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
title: results[i].text,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
complete = true;
});
while (!complete);
}
}
}
});
答案 1 :(得分:0)
最后我用extjs / sencha实现了它。我遇到的第二个问题是谷歌地图服务的限制(我有很多配额超出例外)。所以这不是问题的答案。所以我将另一个答案标记为正确,因为它更接近问题。无论如何,我最终得到的代码可能对某人有帮助。
App.stores.offers = new Ext.data.Store({
model: 'Offer',
(...)
listeners: {
load: function(store, records, success){
this.addEvents( "refresh_locations", "locations_updated" );
for (var i=0; i < store.data.length; i++) {
store.fireEvent("refresh_locations", store , store.getAt(i), "load" );
}
},
refresh_locations: function(store, record, method){
if (record.get("location") == null || record.get("location") == ""){
Ext.Ajax.request({
url: 'api/partner2sport/find_location',
params: {
"city" : record.get("place")
},
success: function(response, options) {
db_check = Ext.decode(response.responseText)["success"];
if (db_check){
var latlngStr = Ext.decode(response.responseText)["location"].replace(/\(|\)/g,"").split(",",2)
var lat = parseFloat(latlngStr[0]) - (Math.random() / 100);
var lng = parseFloat(latlngStr[1]) - (Math.random() / 100);
var latlng = new google.maps.LatLng(lat, lng);
record.set("location", latlng);
}else{
geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
'address': record.get("place")
},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
record.set("location", results[0].geometry.location);
Ext.Ajax.request({
url: 'api/partner2sport/set_location',
params: {
"city" : record.get("place"),
"location": record.get("location")
}
});
}
}
);
}
},
failure: function(response, options) {
console.log("bad request");
}
});
}
},
(...)