如何在Web应用程序的单独文件中回调Google Maps init

All*_*OOP 7 html javascript google-maps google-maps-api-3 angularjs

当我有Google Maps API代码段时:

<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
Run Code Online (Sandbox Code Playgroud)

index.html,我得到了错误:Uncaught InvalidValueError: initMap is not a function.

我希望在我的Yeoman-scaffolded AngularJS Web应用程序中保留我的所有bower_componentCSS,API和脚本声明index.html.我实际上试图重新创建的地图将在另一条路线上,我们将其称为"afterlogin"路线,只是一张基本地图.我将js和html html组件分成了afterlogin.jsafterlogin.html

造成这种情况的原因有很多.其中一个是在调整调用以匹配命名空间的问题,/sf/answers/2412677711/.这需要角度服务吗?如果是这样,该服务如何initMap在Google map api片段中使用该功能及其调用?

其中一个复杂因素是订单.我是新来的Web应用开发,但我可以告诉的index.html第一负载,使用在片断的URL进行回调到initMap未在特色功能<script>...</script>index.html文件,也没有在app.js文件中.相反,由于init函数位于路径的js代码中,因此无法看到它,因此需要某种类型的"命名空间"版本的调用.这甚至从登录路线导致控制台错误,这甚至不是div地图的位置.

----编辑:----

还要注意,在这种情况下,这没有做到这一点:

window.initMap = function(){
//...
}
Run Code Online (Sandbox Code Playgroud)

这也不适用,因为函数永远不会被调用:Uncaught InvalidValueError:initMap不是函数

- - - - - -

afterlogin.js

angular.module('myappproject').controller('AfterloginCtrl', function ($scope) {

  function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 17,
      center: {lat: -33.8666, lng: 151.1958}
    });

    var marker = new google.maps.Marker({
      map: map,
      // Define the place with a location, and a query string.
      place: {
        location: {lat: -33.8666, lng: 151.1958},
        query: 'Google, Sydney, Australia'

      },
      // Attributions help users find your site again.
      attribution: {
        source: 'Google Maps JavaScript API',
        webUrl: 'https://developers.google.com/maps/'
      }
    });

    // Construct a new InfoWindow.
    var infoWindow = new google.maps.InfoWindow({
      content: 'Google Sydney'
    });

    // Opens the InfoWindow when marker is clicked.
    marker.addListener('click', function() {
      infoWindow.open(map, marker);
    });
  }
 });
Run Code Online (Sandbox Code Playgroud)

afterlogin.html

<!DOCTYPE html>
<html>
    <head>
        <title>after login page</title>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
        <meta charset="utf-8">
        <style>
            html, body {
                height: 100%;
                margin: 0;
                padding: 0;
                }
            #map {
                height: 100%;
            }
        </style>
    </head>
    <body>

        <div id="map"></div>

    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

Mos*_*Feu 13

由于Google Maps SDK脚本加载了synchronic(由于该async属性),因此callbackURL中有参数.

要解决这个问题,您需要了解asyncgoogle sdk中的机制

async属性允许浏览器在加载Maps JavaScript API时呈现您网站的其余部分.API准备就绪后,将调用使用callback参数指定的函数.

https://developers.google.com/maps/documentation/javascript/tutorial#Loading_the_Maps_API

因此解决方案是加载脚本synchronic:

在加载Maps JavaScript API的脚本标记中,可以省略async属性和回调参数.这将导致API的加载被阻止,直到下载API.

这可能会减慢页面加载速度.但这意味着您可以编写后续脚本标记,假设已加载API.

https://developers.google.com/maps/documentation/javascript/tutorial#sync

  1. 您可以通过async这种方式删除属性,页面将停止运行,直到脚本完成下载并在页面上运行.因此,当浏览器访问您的代码时,所有SDK对象都将可用.
  2. 现在,因为没有代码调用该initMap函数(记住:谁调用它,它是仅在async模式下调用它的sdk脚本),你需要自己调用它.所以,只需在控制器的末尾调用它.


mor*_*ler 10

我可以通过使用回调并像您一样声明该initMaps函数来在代码中修复它:window

window.initMap = function(){
  //...
}
Run Code Online (Sandbox Code Playgroud)

然而,诀窍是在加载 Google 地图之前加载我的自定义 JS(其中还包括上面的 声明initMaps) :

<script async src="myCustomJsInclduingInitMapsFunction.js"></script>
<script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

  • 事实上,它确实有效。但在 Typescript 中我必须使用 `window['initMaps'] = function() { ... }`。简单地使用“window.initMaps = ...”是行不通的。 (2认同)