如何在 Web 应用程序的单独文件中回调 Google Maps init [英] How to make a callback to Google Maps init in separate files of a web app

查看:28
本文介绍了如何在 Web 应用程序的单独文件中回调 Google Maps init的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我拥有 Google Maps API 片段时:

When I had my Google Maps API snippet:

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

index.html 中,我收到错误:

in index.html, I got the error:

未捕获的 InvalidValueError: initMap 不是函数

Uncaught InvalidValueError: initMap is not a function

我想将我所有的 bower_component、CSS、API 和脚本声明保留在我的 Yeoman-scaffolded AngularJS Web 应用程序的 index.html 文件中.我实际上试图重新创建的地图将在另一条路线上,我们称之为路线登录后",只是一个 基本地图.我把js和html的html组件分成了afterlogin.jsafterlogin.html

I want to keep all of my bower_component, CSS, API, and script declarations in my index.html file on my Yeoman-scaffolded AngularJS web app. The map I was actually trying to recreate would be on another route, let's call it route "afterlogin", just a basic map. I separated the js and the html html components into afterlogin.js and afterlogin.html

造成这种情况的潜在原因有很多.其中之一是调整调用以匹配命名空间,https://stackoverflow.com/a/34466824/1923016.这需要角度服务吗?如果是这样,该服务将如何进入 initMap 函数及其在 Google 地图 API 片段中的调用?

There are a number of potential causes for this. One of which was presented here as a matter of adjusting the call to match the namespace, https://stackoverflow.com/a/34466824/1923016 . Would this require an angular service? If so, how would the service work into the initMap function and its call in the Google maps api snippet?

复杂性之一是订单.我是网络应用程序开发的新手,但据我所知,index.html 首先加载,使用代码段中的 url 来回调 initMap 函数<script>...</script>index.html 文件和 app.js 中都没有文件.相反,由于 init 函数位于路由的 js 代码中,因此无法看到它,因此需要某种命名空间".调用的版本.这甚至会导致登录路径出现控制台错误,这甚至不是地图的 div 所在的位置.

One of the complications is the order. I'm new to web app dev, but from what I can tell the index.html loads first, uses the url in the snippet to make the callback to the initMap function which is not featured in <script>...</script> in the index.html file nor in the app.js file. Instead, since the init function is in a route's js code, it cannot be seen, hence the need for some kind of "namespace" version of the call. This leads to a console error even from the login route, which is not even where the div for the map is.

---- ----

还要注意,在这种情况下,这并没有起到作用:

Also note that in this case, this did not do the trick:

window.initMap = function(){
//...
}

这也不适用,因为该函数从未被调用:未捕获的 InvalidValueError: initMap 不是函数

This also does not apply, as the function is never called: Uncaught InvalidValueError: initMap is not a function

-- -- -- -- -- --

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

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>

推荐答案

由于 Google Maps SDK 脚本加载同步(由于 async 属性),因此存在 callback URL 中的参数.

Since the Google Maps SDK script load a synchronic (due the async attribute), there is the callback parameter in the URL.

要解决这个问题,需要了解google sdk中的async机制

To solve the problem, you need to understand the async mechanism in google sdk

异步属性可让浏览器在 Maps JavaScript API 加载时呈现网站的其余部分.当 API 准备就绪时,它将调用使用回调参数指定的函数.

The async attribute lets the browser render the rest of your website while the Maps JavaScript API loads. When the API is ready, it will call the function specified using the callback parameter.

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

所以解决方案是同步加载脚本:

So the solution is to load the script synchronic:

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

In the script tag that loads the Maps JavaScript API, it is possible to omit the async attribute and the callback parameter. This will cause the loading of the API to block until the API is downloaded.

这可能会减慢您的页面加载速度.但这意味着您可以在假设 API 已经加载的情况下编写后续脚本标签.

This will probably slow your page load. But it means you can write subsequent script tags assuming that the API is already loaded.

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

  1. 您可以通过这种方式删除 async 属性,页面将停止运行,直到脚本完成下载并在页面上运行.因此,当浏览器访问您的代码时,所有 SDK 对象都将可用.
  2. 现在,由于没有调用 initMap 函数的代码(记住:谁调用了它,是 sdk 脚本仅在 async 模式下调用它),需要自己调用.因此,只需在控制器的末尾调用它即可.
  1. You can remove the async attribute that way, the page will stop running until the script will complete downloaded and run on the page. So, when the browser will get to your code, all the SDK object will be available.
  2. Now, since there is not code that calls to the initMap function (remember: who called it, it was the sdk script which call it only in the async mode), you need to call it by yourself. So, just call it in the end of the controller.

这篇关于如何在 Web 应用程序的单独文件中回调 Google Maps init的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆