webentwicklung-frage-antwort-db.com.de

So rufen Sie Google Maps in separaten Dateien einer Web-App zurück

Als ich mein Google Maps API-Snippet hatte: 

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

in index.html erhielt ich den Fehler: Uncaught InvalidValueError: initMap is not a function.

Ich möchte alle bower_component-, CSS-, API- und Skriptdeklarationen in meiner index.html-Datei auf meiner Yeoman-gerüsteten AngularJS-Web-App aufbewahren. Die Map, die ich eigentlich neu erstellen wollte, würde sich auf einer anderen Route befinden, nennen wir sie Route "afterlogin", nur eine basic map . Ich habe die Komponenten js und html html in afterlogin.js und afterlogin.html getrennt.

Dafür gibt es mehrere mögliche Ursachen. Eines davon wurde hier vorgestellt, um den Aufruf an den Namensraum anzupassen: https://stackoverflow.com/a/34466824/1923016 . Würde dies einen Winkeldienst erfordern? Wenn ja, wie würde der Dienst in die initMap-Funktion und ihren Aufruf im Google-Maps-API-Snippet wirken?

Eine der Komplikationen ist die Reihenfolge. Ich bin neu im Web-App-Entwickler, aber von dem, was ich zum ersten Mal sagen kann, index.html lädt, verwendet die URL im Snippet den Callback für die initMap-Funktion, die weder in <script>...</script> der index.html-Datei noch in der app.js-Datei enthalten ist. Da die init-Funktion im js-Code einer Route enthalten ist, kann sie nicht gesehen werden, daher ist eine Art "Namespace" -Version des Aufrufs erforderlich. Dies führt sogar bei der Anmelderoute zu einem Konsolenfehler, der nicht einmal dort liegt, wo sich die div für die Karte befindet. 

---- BEARBEITEN: ----

Beachten Sie auch, dass dies in diesem Fall nicht ausreicht:

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

Dies gilt auch nicht, da die Funktion nie aufgerufen wird: Uncught InvalidValueError: initMap ist keine Funktion

- - - - - -

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>
6
AlleyOOP

Da das Google Maps-SDK-Skript eine Synchronisierung lädt (aufgrund des Attributs async), befindet sich in der URL der Parameter callback.

Um das Problem zu lösen, müssen Sie den Mechanismus async in Google SDK kennen

Mit dem async-Attribut kann der Browser den Rest Ihrer Website rendern, während die Google Maps JavaScript-API geladen wird. Wenn die API fertig ist, ruft sie die mit dem Callback-Parameter angegebene Funktion auf.

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

Die Lösung besteht also darin, das Skript synchronic zu laden:

In dem Skripttag, das die Google Maps JavaScript-API lädt, können das async-Attribut und der Callback-Parameter weggelassen werden. Dadurch wird das Laden der API blockiert, bis die API heruntergeladen wird.

Dies wird wahrscheinlich das Laden Ihrer Seite verlangsamen. Dies bedeutet jedoch, dass Sie nachfolgende Skript-Tags schreiben können, vorausgesetzt, die API ist bereits geladen.

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

  1. Sie können das async-Attribut auf diese Weise entfernen. Die Seite wird angehalten, bis das Skript vollständig heruntergeladen und auf der Seite ausgeführt wird. Wenn der Browser also Ihren Code erhält, sind alle SDK-Objekte verfügbar.
  2. Da es keinen Code gibt, der die initMap-Funktion aufruft (denken Sie daran: wer ihn angerufen hat, war es das sdk-Skript, das ihn nur im async-Modus aufruft), müssen Sie ihn selbst aufrufen. Rufen Sie es also einfach am Ende des Controllers auf.
13
Mosh Feu

Ich könnte es in meinem Code korrigieren, indem ich den Rückruf verwende und die Funktion initMaps für window wie folgt deklarierte:

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

Der Trick bestand jedoch darin, meinen benutzerdefinierten JS zu laden (der auch die obige Deklaration von initMaps enthält) vor Laden von Google Maps:

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

Hoffe das hilft.

1
morgler