开发者

Callbacks over Callbacks

I want to put markers on a map. The source is a json request, which returns cities.

I've got a function (sencha) that returns the records (asynchronous) and a function (google maps api) that returns the lng, lat for specific cities (asynchronous) and a method (google maps), that puts markers on the map.

The result should be a marker on the map at the location calculated by google with a caption retrieved from the record.

load records

offers = App.stores.offers.load({
    callback: function(records, operation, success){...}
})

get location

geocoder = new google.maps.Geocoder();
geocoder.geocode(
  {'address': adress},
  function(results, status) {...}
}

and set the marker

marker = new google.maps.Marker({
  map: map,
  position: loc,
  title: text
});

What I wan't to do is, load the record, loop over each record, find out about location of the city and put a marker there.

synchronous I would do:

   records = App.stores.offers.load();
   for (var i=0; i < records.length; i++) {
     setMarker( map, getLocation(records[i].data["city"]), cords[i].data["text"]);
   }

What's th开发者_如何转开发e right way to put it together with the asynchronous functions?


I don't really know what does the App.stores.offers.load function do exactly but I'll assume its callback function arguments contain loading results in records variable. In this case loop through records inside callback function and for each call geocode, and on geocode's callback place markers (nothing wrong with this).

EDIT: this is untested and probably not most efficient but should work:

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


In the end I implemented it with extjs / sencha. The second problem I run in to was the restrictions on the google maps service (I had a lot of quota exceeded exceptions). So it's not exactly the answer to the question. So I marked the other answer as correct, because it's closer to the question. Here the code I had in the end anyway, may it help someone.

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");
      }
    });
  }
},

(...)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜