web-dev-qa-db-fra.com

Comment rappeler Google Init dans des fichiers distincts d'une application Web

Lorsque j'ai eu mon extrait de l'API Google Maps: 

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

dans index.html, j'ai eu l'erreur: Uncaught InvalidValueError: initMap is not a function.

Je souhaite conserver toutes mes déclarations bower_component, CSS, API et script dans mon fichier index.html sur mon application Web AngularJS échafaudée par Yeoman. La carte que j'essayais de recréer serait sur une autre route, appelons-la route "afterlogin", juste une carte de base . J'ai séparé les composants js et html html en afterlogin.js et afterlogin.html

Il y a plusieurs causes possibles à cela. L’une d’elles a été présentée ici pour ajuster l’appel afin qu’il corresponde à l’espace de nom, https://stackoverflow.com/a/34466824/1923016 . Cela nécessiterait-il un service angulaire? Si tel est le cas, comment le service fonctionnerait-il dans la fonction initMap et son appel dans l'extrait d'API Google Maps?

Une des complications est la commande. Je suis nouveau dans l'application Web, mais d'après ce que je peux dire, le index.html se charge en premier, utilise l'URL de l'extrait pour rappeler la fonction initMap qui ne figure pas dans <script>...</script> dans le fichier index.html ni dans le fichier app.js. Au lieu de cela, puisque la fonction init est dans le code js d'une route, elle ne peut pas être vue, d'où la nécessité d'une version de "namespace" de l'appel. Cela entraîne une erreur de console même à partir de la route de connexion, ce qui n’est même pas là où se trouve la variable div pour la carte. 

---- MODIFIER: ----

Notez également que dans ce cas, cela n'a pas fait l'affaire:

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

Cela ne s'applique pas non plus, car la fonction n'est jamais appelée: Uncaught InvalidValueError: initMap n'est pas une fonction

- - - - - -

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

Le script SDK de Google Maps chargeant une synchronisation (en raison de l'attribut async), il existe le paramètre callback dans l'URL.

Pour résoudre le problème, vous devez comprendre le mécanisme async dans google sdk.

L'attribut async permet au navigateur de restituer le reste de votre site Web pendant le chargement de l'API JavaScript de Maps. Lorsque l'API est prête, elle appelle la fonction spécifiée à l'aide du paramètre callback.

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

La solution consiste donc à charger le script synchronic:

Dans la balise de script qui charge l'API JavaScript de Maps, il est possible d'omettre l'attribut async et le paramètre de rappel. Le chargement de l'API sera bloqué jusqu'à ce que l'API soit téléchargée.

Cela ralentira probablement le chargement de votre page. Mais cela signifie que vous pouvez écrire les balises de script suivantes en supposant que l'API est déjà chargée.

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

  1. Vous pouvez supprimer l'attribut async de cette façon, la page cessera de s'exécuter jusqu'à ce que le script soit complètement téléchargé et exécuté sur la page. Ainsi, lorsque le navigateur obtiendra votre code, tout l’objet SDK sera disponible.
  2. Maintenant, comme il n'y a pas de code qui appelle la fonction initMap (rappelez-vous: qui l'a appelé, c'est le script sdk qui l'appelle uniquement en mode async), vous devez l'appeler vous-même. Alors, appelez-le à la fin du contrôleur.
13
Mosh Feu

Je pourrais le réparer dans mon code en utilisant le rappel et en déclarant la fonction initMaps sur window comme vous l'avez fait:

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

Cependant, le truc était de charger mon JS personnalisé (qui inclut également la déclaration ci-dessus de initMaps) avant chargement de 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>

J'espère que cela t'aides.

1
morgler