如何使用RequireJS加载Google Maps API?

45

我正在努力使用requireJS加载gmaps api。这是我尝试的内容:

requirejs.config({
    urlArgs: "noCache=" + (new Date).getTime(),
    paths : {
        "jquery": "vendor/jquery-1.8.2.min",
        "bootstrap": "vendor/bootstrap.min",      
        "underscore": "libs/underscore-min",
        "backbone": "libs/backbone-min",    
        "template": "libs/template",
        "gmaps": "http://maps.google.com/maps/api/js?v=3&sensor=false"
    },
    shim: {
        'backbone': {
            deps: ['jquery', 'underscore'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'bootstrap': {
            deps: ['jquery']
        },
        'gmaps': {
            deps: ['jquery']
        },
        'main':{
            deps: ['jquery','gmaps']   
        }
    }
});

require(["main"], function (main) {})

但是在main.js中,当我尝试实例化geocoder时,我得到了“undefined is not a function”错误。

var geocoder = new google.maps.Geocoder();

我在做什么方面可能出错了?


有任何网络错误吗?地图API JS是否真正加载? - Paul Grime
1
没有,它还没有被加载... - hjuster
这个答案可能会有所帮助 - https://dev59.com/h2w15IYBdhLWcg3wy-vO。我没有API密钥,所以对我来说可能不完全有效。看起来必须请求加载地理编码器。 - Paul Grime
请问您能否展示一下如何从您的configure.js中定义的gmaps转换为新的google.maps.Geocoder()吗? - KingAndrew
7个回答

64

我已经使用async插件解决了它。

一个快速的例子是:

require.config({
    paths: {
        'async': 'lib/requirejs-plugins/src/async'
    }
});

define(['async!http://maps.google.com/maps/api/js?sensor=false'], function() {
    // Google Maps API and all its dependencies will be loaded here.
});

7
http://blog.millermedeiros.com/requirejs-2-0-delayed-module-evaluation-and-google-maps/ - Marcel de Castilho
对我来说,断点没有到达回调函数,在你注释“//Google Maps...would be loaded here.”的地方。 - Davut Gürbüz
如何安装异步插件? - Zorox

12

感谢 user1706254 提供的官方文档:https://github.com/millermedeiros/requirejs-plugins/。在这份文档中,原来使用的关键字是 'define' ,但对我无效,使用 'require' 则能正常工作。

我无法直接加载:

require(["goog!maps,3,other_params:sensor=false"], function(){});

但是使用异步方式就行了:

require(['async!http://maps.google.com/maps/api/js?sensor=false'], function(){});

嗯,对我来说它是有效的。goog模块要求在路径中定义'async'和'propertyParser',就像那样,包括驼峰式大小写。顺便说一句,sensor现在没有任何作用,可以省略。 - light24bulbs
有人能让API密钥与此配合使用吗?据我所知,这不支持在URL中包含API密钥。将其硬编码到插件中并不难,但我认为这是缺少重点的做法。现在我更喜欢使用异步模块手动请求URL,因为这可以给你完全的控制。 - light24bulbs

5
您不需要使用async插件来使用require.js加载Google Maps。只需使用一个简单的shim配置即可实现目标:

shim

require.config({
    paths: {
        gmaps: '//maps.googleapis.com/maps/api/js?' // question mark is appended to prevent require.js from adding a .js suffix
    },
    shim: {
        gmaps: {
            exports: 'google.maps'
        }
    }
});

require(['gmaps'], function (gmaps) {
    var center = {lat: -34.397, lng: 150.644}; 
    var map = new gmaps.Map(document.getElementById('map'), {
        center: center,
        zoom: 8
    });
    new gmaps.Marker({
        map: map,
        position: center
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script>

<div id="map" style="width: 100%; height: 200px"></div>


4

还有一个 goog 插件(需要 async 和 propertyParser),可在 github 上获取。

谷歌地图的使用示例:

require(["goog!maps,3,other_params:sensor=false"], function(){});

这是做法。对我来说,使用谷歌地点没有任何问题:goog!maps,3,other_params:key=XXX&libraries=places - sucotronic

4

0

@hjuster的回答为我指明了方向,我通过回调函数解决了问题。

define(['async!http://maps.google.com/maps/api/js?key=YOURKEY!callback'],
    function (_ExpectedMap) {
                              callback(); 
                           });

请注意URL末尾的!callbackasync!开头,当加载操作完成时将调用回调方法。
function callback()
{
    //Now load google maps API dependant libraries
    require(['gmapsLib'], function (googlemaps) {
                     window.GMaps = googlemaps;
                   }
}

我最近注意到另一个问题,使用了另一个函数(onLoad)而不是回调来防止超时错误。有趣。


-3

由于某些原因无法使插件正常工作,但这个解决方法拯救了我的一天:

 require(['https://apis.google.com/js/client.js?onload=doNothing'], function() {
    // Poll until gapi is ready
    function checkGAPI() {
      if (gapi && gapi.client) {
        self.init();
      } else {
        setTimeout(checkGAPI, 100);
      }
    }

    checkGAPI();
  });
});

每100毫秒检查一次gapi是否已准备好,直到它最终加载。

在这篇文章http://dailyjs.com/2012/12/06/backbone-tutorial-2/中找到了这段代码。

我想你也可以尝试一下。

if (google && google.maps && google.maps.Geocoder) {
    // now google.maps.Geocoder is gonna be defined for sure :)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接