Foreach绑定与谷歌地图标记的自定义绑定

时间:2015-12-03 17:24:39

标签: google-maps knockout.js foreach

现在我有一个自定义绑定,它从我的viewModel中的observableArray中获取信息,遍历for循环,并为每个位置创建一个标记。我想摆脱for循环并在我的DOM中使用foreach绑定,但我似乎无法按照我希望的方式工作。

http://codepen.io/ntibbs/pen/ZbPPBm?editors=101

我尝试在自定义绑定中删除所有for循环内容(for(...){}和[i])并尝试使用foreach添加foreach绑定而不使用容器元素方法

<!-- ko foreach: locations -->
  <div id='marker' data-bind="marker: { locations }"></div>
<!-- /ko -->

但我无法弄清楚如何让它发挥作用。

1 个答案:

答案 0 :(得分:0)

您可以使用以下绑定来迭代位置:

<!-- ko foreach: locations -->
     <span data-bind="marker: $data"></span>
<!-- /ko -->

示例

&#13;
&#13;
ko.bindingHandlers.marker = {

    infowindow: null,

    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        var map = bindingContext.$parent.mapControl;
        var location = valueAccessor().location;
        var latLng = new google.maps.LatLng(location.lat, location.lng);
        var marker = new google.maps.Marker({
            position: latLng,
            map: map,
            icon: "http://chart.apis.google.com/chart?chst=d_bubble_icon_text_small_withshadow&chld=swim|bbT|" + location.name + "|24527A|E0EBEB",
            title: location.name
        });

        marker.addListener('click', function () {
            ko.bindingHandlers.marker.openInfoWindow(map, marker);
        });
    },



    openInfoWindow: function (map, marker) {
        var contentString = '<div">' + marker.getTitle() + '</div>';
        if (this.infowindow) {
            this.infowindow.close();
        };
        this.infowindow = new google.maps.InfoWindow({
            content: contentString,
            pixelOffset: new google.maps.Size(50, 0),
        });
        map.setZoom(9);
        map.setCenter(marker.getPosition());
        this.infowindow.open(map, marker);
        google.maps.event.addListener(this.infowindow, 'closeclick', function () {
            map.setZoom(7);
            //map.setCenter(mapOptions.center);
        });
    }
};


google.maps.event.addDomListener(window, 'load', function () {

 
    //1.create map
    var mapOptions = {
            zoom: 7,
            center: new google.maps.LatLng(36.55, -77.0167),
            mapTypeId: google.maps.MapTypeId.TERRAIN
    };
    var map = new google.maps.Map(document.getElementById('map'), mapOptions);


    var viewModel = {
        locations: ko.observableArray([
          { name: "Virginia Beach", lat: 36.852926, lng: -75.977985, state: 'Virginia' },
          { name: "Chincoteague Island", lat: 37.93317, lng: -75.378809, state: 'Virginia' },
          { name: "Atlantic City", lat: 39.364283, lng: -74.422927, state: 'New Jersey' },
          { name: "Ocean city", lat: 38.336503, lng: -75.084906, state: 'Maryland' },
          { name: "Oakacroke", lat: 35.114615, lng: -75.98101, state: 'North Carolina' },
          { name: "Nags Head", lat: 35.957392, lng: -75.624062, state: 'North Carolina' },
          { name: "Emerald Isle", lat: 34.677940, lng: -76.950776, state: 'North Carolina' }
        ]),
        mapControl: map
    };

    ko.applyBindings(viewModel);
});
&#13;
*{
  font-family: sans-serif;
}
h1 {
  position: absolute;
  width: 300px;
  top: 0px;
  left: 75px;
  font-size: 135px;
  color: #24527A;
  font-family: 'Voltaire', sans-serif;
  text-shadow: 7px 7px 2px rgba(0,0,0,.5);
  z-index: 1;
}
#map { 
  height:800px;
  width:100%;
}
&#13;
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.4.0.js"></script>

<div id="map"></div>
<!-- ko foreach: locations -->
     <span data-bind="marker: {location: $data}"></span>
<!-- /ko -->
&#13;
&#13;
&#13;

Modified example: Plunker