Knockoutjs google maps与Ajax调用绑定



我通过广泛的阅读和修补对这段代码挠了挠头,但似乎无法让自己在谷歌地图上应用 KNOCKOUT JS。让我知道我是否在正确的轨道上。我正在渲染带有一些默认标记的地图(按预期工作),然后想使用从选择表单上的更改事件触发的 ajax 调用派生的点来更新它们。我可能缺少一些非常基本的东西,因为这是我第一次使用带有KO的谷歌地图,并且不太确定在哪里将V和VM分开

my HTML 
// html form with select option in jinja2
<form action=""> 
<select name="categories" onchange="showCategory(this.value)">
<option value="">Select Category</option>
{% for c in cat %}
<option value={{c.id}}>{{c.name}}</option>
{% endfor %}
</select>
</form>
//a div to display XMLHttpRequest response to make sure am getting that part right
<div id="demo">
<h1>The XMLHttpRequest Object</h1>
</div>
//the map div   
<div id="map"></div>
<script>

我的变量与加 XMLHttpRequest

//Declare Map variable and markers array
var map;
var marker;
var markers = [];
var lat = -1.2886009200028272;
var lng = 36.822824478149414;
var features = [
{
name: name,
position: {lat:lat, lng: lng},
type: 'parking'
},
{
name: name,
position: {lat:-1.287785734541792, lng: 36.82161211967468},
type: 'info'
}
];
// make XMLHttpRequest and update the above variables
function showCategory(cat_id) {
var xhttp;    
if (cat_id == "") {
document.getElementById("demo").innerHTML = "Please select a Category";
return;
}
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var my_text = this.responseText;
obj = JSON.parse(my_text);
raw_lat = obj.Addresses[0].lat
lat = parseFloat(raw_lat)
raw_lng = obj.Addresses[0].lng
lng = parseFloat(raw_lng)
features = [
{
position: {lat:lat, lng: lng},
type: 'info'
},
{
name: name,
position: {lat:-1.287785734541792, lng: 36.82161211967468},
type: 'parking'
}
];
//check to confirm am getting a response
document.getElementById("demo").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "/loc/"+cat_id, true);
xhttp.send();
};
//Fetch relevant map icons from Google
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
var icons = {
parking: {
icon: iconBase + 'parking_lot_maps.png'
},
library: {
icon: iconBase + 'library_maps.png'
},
info: {
icon: iconBase + 'info-i_maps.png'
}
};

地图代码

//create the map and the view model   
function initMap() {
var ViewModel = function() {
var self = this
self.lat = ko.observable(lat)
self.lng = ko.observable(lng)
self.map = new google.maps.Map(document.getElementById("map"), {
zoom: 16,
center: new google.maps.LatLng(self.lat(), self.lng()),
mapTypeId: 'roadmap'
});

self.updatedfeatures = ko.observableArray(features.slice());
// Create markers.
self.updatedfeatures().forEach(function(feature) {
marker = new google.maps.Marker({
position: feature.position,
icon: icons[feature.type].icon,
map: self.map
});
markers.push(marker);
});
};
ko.applyBindings(new ViewModel());
};

为此,事实证明这是一种矫枉过正。要点是XMLHttpRequest是异步的,ajax调用将设置lat和lng值,但在javascript的其余部分运行之后。当然,js 中有希望,KO中有延迟更新,但我意识到有一种更简单的方法来完成同样的事情。我只是将 XMLHttpRequest 函数移动到映射函数中,并使用document.getElementById("myId").addEventListener("change", myFunction);在选择值更改时发出 ajax 请求,然后更新标记。我不需要KO,但当然它会派上用场,因为我在电话后对制造商进行了进一步的分类

所以这是我更改的代码部分

//create the map and the view model   
function initMap() {
var ViewModel = function() {
var self = this
self.lat = ko.observable(lat)
self.lng = ko.observable(lng)
self.lng.subscribe(function(newValue) {
alert("new values are " + newValue);
});
self.map = new google.maps.Map(document.getElementById("map"), {
zoom: 16,
center: new google.maps.LatLng(self.lat(), self.lng()),
mapTypeId: 'roadmap'
});

self.updatedfeatures = ko.observableArray(features);
// Create markers.
self.updatedfeatures().forEach(function(feature) {
self.marker = new google.maps.Marker({
position: feature.position,
icon: icons[feature.type].icon,
map: self.map
});
markers.push(self.marker);
});
document.getElementById("my_cats").addEventListener("change", myFunction);
function myFunction() {
var cat_id = document.getElementById("my_cats").value;
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var my_text = this.responseText;
obj = JSON.parse(my_text);
var raw_lat = obj.Addresses[0].lat;
lat = parseFloat(raw_lat);
var raw_lng = obj.Addresses[0].lng;
lng = parseFloat(raw_lng);
features = [
{
position: {lat:lat, lng: lng},
type: 'parking'
},
{
name: name,
position: {lat:-1.287785734541792, lng: 36.82161211967468},
type: 'parking'
}
];
features.forEach(function(feature) {
marker = new google.maps.Marker({
position: feature.position,
icon: icons[feature.type].icon,
map: self.map
});
markers.push(marker);
});
}
};
xhttp.open("GET", "/loc/1", true);
xhttp.send();
}

};
ko.applyBindings(new ViewModel());
};

最新更新