【问题标题】:Google Maps API: Setting up callbacks for adding markers/polylineGoogle Maps API:设置回调以添加标记/折线
【发布时间】:2016-03-26 13:58:14
【问题描述】:

我正在尝试将折线添加到生成的 Google 地图中。折线的坐标是使用 jQuery(getJSON 函数)从我的 Web 服务器上的 JSON 文件中获取的。但是,我遇到了回调问题。我在一个单独的 JavaScript 文件中定义了三个函数,它们是:

function initMap(callback) {

    map = new google.maps.Map(document.getElementById('map-canvas'), {
        center: {lat: 34.397, lng: 150.644},
        scrollwheel: false,
        zoom: 2
    });

    callback();
}

.

function setPath(callback) {

   $.getJSON('./expOneActivityData.json',

       function (data) {

           //Some looping contstruct to navigate through my JSON file.   
       }
   })

   callback();
};

.

function addPath() {

    var trekLine = new google.maps.Polyline({

        path: expeditionCoordinates,
        geodisc: true,
        stokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2
    });

    trekLine.setMap(map);

}

expeditionCoordinates 是一个数组,每个元素都是一个具有纬度和经度属性的对象。这被声明为全局变量,值初始化发生在 setPath() 的循环中。

在我的 HTML 文件中,我有:

<script src="https://maps.googleapis.com/maps/api/js?key=myKey&callback=initMap">

当我尝试在脚本标记中用 initMap(setPath(addPath)) 替换 initMap 时,我收到来自 Google 的 400 Bad request。当然,在脚本标签中只有“callback=initMap”会给出:

TypeError: callback is not a function

与 initMap 定义中的 callback() 一致。

那么如何将函数传递给 googleapis,函数本身也有回调? (顺便说一句,我的循环结构很好)。我尝试将“延迟”添加到 googleapi 脚本标签,以及链接到我的 JavaScript 文件的标签中。我删除了所有回调的东西,只执行了循环。我希望 expeditionCoordinates 数组能够在执行 googleapi 脚本标记之前完成初始化,尽管这也不起作用(地图仍在加载,只是没有折线)。

我对 Javascript 还很陌生,它是异步的,但我确实了解它们的工作原理,并且已经成功地在基本级别上使用它们一周左右。

(这实际上让我想到了一个附带问题。到目前为止,我只使用了一个回调。我希望是这样的:

initMap(setPath)

当 setPath 的定义作为参数传递时,它没有附加 (),因此不会立即执行。虽然在 setPath 中添加了一组括号,因为它还需要一个回调(addPath),这是否意味着它会立即执行?)

【问题讨论】:

  • 异步加载器的回调函数(initMap)不能带任何参数,它是一个函数指针。

标签: javascript google-maps google-maps-api-3 callback polyline


【解决方案1】:

提供的示例存在几个问题:

1) 加载 Google Maps API 时,callback 参数接受 回调函数名,函数本身应该有 以下签名:

function initMap() {
   //...
}

在哪里

<script src="https://maps.googleapis.com/maps/api/js?key=myKey&callback=initMap" async defer></script>

这种方式只能指定无参数回调函数。

2) 由于jQuery.getJSON() 默认为async,并且您正在传递函数回调,所以setPath 函数的实现应该是这样的:

function setPath(callback) {
    $.getJSON('./expOneActivityData.json',
        function (data) {
            callback(data);
        }
    );
};

工作示例

function initMap() {
    var map = new google.maps.Map(document.getElementById('map-canvas'), {
        center: { lat: 34.397, lng: 150.644 },
        scrollwheel: false,
        zoom: 2
    });

    setPath(function(data) {
        addPath(map,data);
    });
}

function setPath(callback) {
    $.getJSON('https://gist.githubusercontent.com/vgrem/91ba4d694157169b112c/raw/5bdd81c6f5bdfa5ba2d0ca8d5494129b329399d8/expOneActivityData.json',
        function (data) {
            callback(data);
        }
    );
};


function addPath(map,expeditionCoordinates) {
    var trekLine = new google.maps.Polyline({
        path: expeditionCoordinates,
        geodisc: true,
        stokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2
    });
    trekLine.setMap(map);
}
html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#map-canvas {
    height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&callback=initMap"
            async defer></script>

【讨论】:

    【解决方案2】:

    您不能在 Google Maps Javascript API v3 脚本包含的 callback 参数中传递参数。

    这行不通:

    <script src="https://maps.googleapis.com/maps/api/js?key=myKey&callback=initMap(setPath(addPath))"></script>
    

    如您所见。这样的事情应该:

    function initMap() {
        map = new google.maps.Map(document.getElementById('map-canvas'), {
            center: {lat: 34.397, lng: 150.644},
            scrollwheel: false,
            zoom: 2
        });
        setPath(addPath));
    }
    
    function setPath(callback) {
      $.getJSON('./expOneActivityData.json',
        function(data) {
          // Some looping contstruct to navigate through my JSON file.
          // create the expeditionCoordinates array
          callback(expeditionCoordinates);
        }
      );
    };
    
    function addPath(expeditionCoordinates) {
      var trekLine = new google.maps.Polyline({
        path: expeditionCoordinates,
        geodisc: true,
        stokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2
      });
    
      trekLine.setMap(map);
    }
    

    使用它来异步加载 API:

    <script src="https://maps.googleapis.com/maps/api/js?key=myKey&callback=initMap" async defer></script>
    

    【讨论】:

      【解决方案3】:

      不过,您可以通过add a one-time event listener 模拟发送回调。

      var map;
      
      function initMap(mapId, latLong, callback) {
          //...
      
          map = new google.maps.Map(document.getElementById(mapId), {
              zoom: 16,
              center: latlng
          });
      
      
          // This is what you're interested in...
          if ($.isFunction(callback)) {
              google.maps.event.addListenerOnce(map, 'tilesloaded', callback);
          }
      }
      

      这使回调远离脚本src URL 和您的代码程序,尽管在您已经将new Map 代码松散之后添加事件侦听器似乎有点奇怪。

      请注意,尽管它的逻辑更线性一些,但它的加载速度可能不如 Vadim 的回答中的“正确方式”异步加载。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-01
        • 1970-01-01
        • 2015-10-27
        • 2014-11-05
        • 1970-01-01
        • 1970-01-01
        • 2014-02-14
        • 2016-08-25
        相关资源
        最近更新 更多