0

Je travaille sur une application Google Maps simple en utilisant la bibliothèque KnockoutJS - ou du moins cela semblait assez simple dans son concept. Après avoir lu sur KnockoutJS et travaillé sur quelques exemples, j'ai rassemblé les parties initiales. Le code html est juste la carte, je vise à remplir la liste dès que je franchirai le premier obstacle. L'obstacle est dans le Javascript. Voici le code de référence:Variable globale non accessible à ViewModel dans KnockoutJS

"use strict"; 

var map; 
var center; 
var defaultBounds; 
var placesServices; 

//LocationObject created to hold data for locations generated from google.places.nearbySearch 
var LocationObject = function(data){ 

    this.position = data.geometry.location; 
    this.lat = data.geometry.location.lat; 
    this.lng = data.geometry.location.lng; 
    this.name = data.name; 
    this.placeID = data.place_id; 
    this.rating = data.rating; 
    this.types = data.types; 
    this.linkToPhoto = data.html_attributions; 

}; 



function initMap(){ 

    map = new google.maps.Map(document.getElementById('map'), { 
     center: center, 
     zoom: 17, 
     mapTypeId: 'satellite', 
     draggable: true, 
     zoomControl: false, 
     scrollwheel: true, 
     disableDoubleClickZoom: true 
    }); 

    defaultBounds = new google.maps.LatLngBounds(
     new google.maps.LatLng(47.614217, -122.317981),new google.maps.LatLng(47.612975, -122.316291)); 
    map.fitBounds(defaultBounds); 

    placesServices = new google.maps.places.PlacesService(map); 

} 


    //ViewModel created to observe changes on the map 
var MapViewModel = function(){ 
    var self = this; 

    self.testarr = ko.observableArray([ 
     { firstName: 'Bert', lastName: 'Bertington' }, 
     { firstName: 'Charles', lastName: 'Charlesforth' }, 
     { firstName: 'Denise', lastName: 'Dentiste' } 
    ]); 

    self.locations = ko.observableArray([]); 
    self.markers = []; 

    this.getNearbyLocations = function(){ 
     if(placesServices === undefined){ 
      placesServices = new google.maps.places.PlacesService(map); 
     } 

     var request = { 
      location: center, 
      radius: getBoundsRadius(defaultBounds), 
      type: ['establishment'] 
     }; 

     placesServices.nearbySearch(request, function(results, status) { 
      if (status === google.maps.places.PlacesServiceStatus.OK) { 
       for (var i = 0; i <= 18; i++) { 
        var marker = new google.maps.Marker({ 
         map: map, 
         position: results[i].geometry.location, 
         animation: google.maps.Animation.DROP 
        }); 
        self.locations.push(new LocationObject(results[i])); 
        self.markers.push(marker); 
       } 
      } else{ 
       alert("We were not able to find any nearby locations in this Neighbourhood."); 
      } 
     }); 
    }; 

    this.init = function(){ 

     self.getNearbyLocations(); 

    }; 
}; 


var myMapViewModel = new MapViewModel(); 
myMapViewModel.init(); 
ko.applyBindings(myMapViewModel); 



/* Utility Functions */ 
function getBoundsRadius(bounds){....} 

L'erreur est:

Uncaught ReferenceError: google is not defined 
at MapViewModel.getNearbyLocations 

et je ne comprends pas pourquoi ce n'est pas reconnu ici, lorsque la carte des charges se premier sans problème, mais ici il get pendu.

Voici le code html pour référence, mais il ne devrait pas être un problème là:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
    <!-- Required meta tags --> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 

    <!-- Per Google guideline scheduled for the M65 release, css has been moved to an importer --> 
    <link rel="import" href="importer.htm"></link> 

    <!-- Bootstrap CSS --> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"> 


    </head> 
    <body> 
    <div class="container-fluid"> 
    <div class="row"> 
     <div class="col-xs-12 col-md-4"> 
      <!-- List goes in this column. --> 

      </div> 
     </div> 
     <div class="col-xs-12 col-md-8"> 
      <!-- Map goes into this column. --> 
      <div id="map" style="width:100%;height:100vh;"></div> 
     </div> 
     </div> 
    </div> 

<!-- jQuery first, then Popper.js, then Bootstrap JS --> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script> 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script> 
<!-- Optional JavaScript --> 
<script src="js/knockout.js" ></script> 
<script src="js/app.js"></script> 
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC-1EdIyUOb74oGG_mEoPvJTAGCSJvSQms&callback=initMap&libraries=places"></script> 
</body> 

+0

Essayez d'ajouter une référence de script cartes avant 'app.js' – adiga

+0

Vous pouvez également consulter la répondre à [cette question] (https://stackoverflow.com/questions/38627259/how-to-make-a-callback-to-google-maps-init-in-separate-files-of-a-web-app – user3297291

Répondre

1

Je pensais aussi que l'erreur était parce que votre app.js est déclenchées avant que les cartes scénario. Mais j'ai essayé de le changer, même erreur, et j'ai également essayé de supprimer le paramètre async (comme suggéré par le commentaire de user3297291), toujours la même erreur. Théoriquement, il should have worked.

Mais cela a fonctionné - envelopper les 3 dernières lignes de votre code app.js dans une fonction ready():

$(document).ready(function(){ 
    var myMapViewModel = new MapViewModel(); 
    myMapViewModel.init(); 
    ko.applyBindings(myMapViewModel); 
}); 
+0

Oui, j'ai testé toutes ces alternatives hier aussi, avec le même résultat que vous avez trouvé. Aussi, parce que la carte était en train de charger et d'être stockée dans la variable globalement déclarée, j'ai pensé qu'elle devrait être accessible. À un moment donné, j'ai essayé une implémentation où je transmettais des variables dans les fonctions respectives, mais cela avait le même résultat. Je vais ajouter l'option jquery ce soir et approuver une fois confirmé. – aleksandar

+0

J'ai fini par devoir l'emballer dans un délai d'attente, mais cela m'a assez proche - merci! – aleksandar