单击列表项

时间:2016-07-20 01:26:44

标签: google-maps-api-3 knockout.js

我在屏幕的一侧有一个项目列表,另一个是谷歌地图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());
}

https://github.com/matosb2/P5/tree/develop

1 个答案:

答案 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);