2017-10-10 56 views
0

我正在使用KnockoutJS庫開發一個簡單的Google Maps應用程序,或者至少它在概念上看起來夠簡單。 在閱讀了KnockoutJS並編寫了一些示例之後,我將最初的部分放在一起。到目前爲止,html只是地圖,我的目標是儘快填充列表,一旦我完成第一個障礙。這個障礙在Javascript中。下面是引用代碼:KnockoutJS中ViewModel無法訪問的全局變量

"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){....} 

的錯誤是:

Uncaught ReferenceError: google is not defined 
at MapViewModel.getNearbyLocations 

,我不知道爲什麼它沒有被這裏的認可,在地圖本身首先加載沒有問題,但在這裏得到的掛了。

下面是引用的HTML,但不應該存在一個問題:

<!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

嘗試之前'app.js' – adiga

+0

你可能也想看看地圖新增腳本參考回答[此問題](https://stackoverflow.com/questions/38627259/how-to-make-a-callback-to-google-maps-init-in-separate-files-of-a-web-app ) – user3297291

回答

1

我也認爲錯誤是因爲你的app.js的地圖之前被稱爲腳本。但我試着改變它,同樣的錯誤,我也嘗試刪除async參數(如user3297291的評論所建議的),仍然是同樣的錯誤。理論上它should have worked

但這個工作 - 換一個ready()函數內的最後3行的app.js代碼:

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

是的,我昨天也測試了所有這些替代方法 - 結果與您找到的結果相同。另外,因爲地圖正在加載並存儲在全局聲明的變量中,所以我認爲它應該是可訪問的。有一次,我嘗試了一個實現,將變量傳遞到各個函數中,但結果相同。我將在今晚添加jquery選項,並確認一次。 – aleksandar

+0

我最終不得不在暫停時將它包裹起來,但這讓我感覺很近 - 謝謝! – aleksandar