我在屏幕的一侧有一个项目列表,另一个是谷歌地图api显示标记。我希望在点击相应的列表项时弹出任何特定标记的信息窗口。当你点击实际的标记时,我已经设法让标记的信息窗口弹出,但是现在我想让它与我创建的列表一起工作。例如,当我点击列表中的麦迪逊广场花园时,我希望麦迪逊广场花园标记在谷歌地图api中显示信息窗口。
这里是使用knockout的html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/style.css">
<title>Neighborhood Map Project</title>
</head>
<body>
<div id="searchmenu">
<input id="searchbox"placeholder="Search..." type="search" daatabind="value: query, valueUpdate: 'keyup'" autocomplete="off">
<div id="menu">
<ul data-bind="foreach: locations">
<li data-bind="text: name"></li>
</ul>
</div>
</div>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDsK_DgDME2t1k3F0AFiP52F28hDu9nie4&callback=initMap" async defer></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
和js如下:
var locations = [{
name: "Red Bull Arena",
address: "600 Cape May St, Harrison, NJ 07029",
lat: 40.737046,
long: -74.150361
}, {
name: "MetLife Stadium",
address: "1 MetLife Stadium Dr, East Rutherford, NJ 07073",
lat: 40.813091,
long: -74.074209
}, {
name: "World Trade Center",
address: "285 Fulton St, New York, NY 10007",
lat: 40.713175,
long: -74.013104
}, {
name: "Zeppelin Hall Biergarten",
address: "88 Liberty View Dr, Jersey City, NJ 07302",
lat: 40.715120,
long: -74.046754
}, {
name: "Prudential Center",
address: "25 Lafayette St, Newark, NJ 07102",
lat: 40.733617,
long: -74.171150
}, {
name: "Madison Square Garden",
address: "4 Pennsylvania Plaza, New York, NY 10001",
lat: 40.750691,
long: -73.993476
}];
var Location = function(data) {
this.name = ko.observable(data.title);
this.address = ko.observable(data.address);
this.lat = ko.observable(data.lat);
this.long = ko.observable(data.long);
};
var viewModel = function() {
var self = this;
this.locationList = ko.observableArray([]);
locations.forEach(function(locationItem) {
self.locationList.push(new Location(locationItem));
});
this.currentLocation = ko.observable(this.locationList()[0]);
this.setLocation = function(clickedLocation) {
self.currentLocation(clickedLocation);
google.maps.event.trigger(clickedLocation.marker, 'click');
};
this.places = ko.observableArray(locations);
this.query = ko.observable("");
};
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: new google.maps.LatLng(40.753011, -74.128069)
});
var infowindow = new google.maps.InfoWindow();
var marker;
function createMarker(latlng, html) {
html = '<h3>' + locations[i].name + '</h3>' + locations[i].address;
latlng = new google.maps.LatLng(locations[i].lat, locations[i].long);
marker = new google.maps.Marker({
position: latlng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, this);
});
return marker;
}
for (i = 0; i < locations.length; i++) {
createMarker(new google.maps.LatLng(locations[i][2], locations[i][3]));
}
ko.applyBindings(new viewModel());
}
答案 0 :(得分:0)
看起来您已经在viewmodel中设置了一个点击处理程序(如setLocation
),所以您真正需要的是点击绑定。
<ul data-bind="foreach: locations">
<li data-bind="text: name, click: setLocation"></li>
</ul>
很好,您的点击处理程序希望将点击的位置作为参数,并that is what the click binding will give it。
但缺少一件事:setLocation
期望该位置对象拥有marker
成员,但您无法在任何地方创建该成员。一种可行的方法是在您调用createMarker
的循环中,只需将标记作为成员添加到locations
的当前元素。哦,那个循环认为locations
是一个数组数组,而不是一个对象数组。它应该看起来像:
for (i = 0; i < locations.length; i++) {
locations[i].marker = createMarker(new google.maps.LatLng(locations[i].lat, locations[i].long));
}
摆脱你的Location
构造函数,它什么都不提供。只需像这样初始化locationList
:
this.locationList = ko.observableArray(locations);