2015-12-03 81 views
0

現在我有一個自定義綁定,從我的viewModel中的observableArray獲取信息,遍歷for循環,併爲每個位置創建一個標記。我想擺脫for循環,並在我的DOM中使用foreach綁定,但我似乎無法按照我希望的方式工作。Foreach綁定自定義綁定谷歌地圖標記

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

我試圖消除所有我的for循環的東西(對於(...){}和[I])的內部我的自定義結合和嘗試添加一個foreach使用foreach結合無容器元件的方法

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

但我只是無法弄清楚如何得到它的工作。

+1

我如果你想從'locations'將位置傳遞給'marker'綁定,那麼它看起來就像'data-bind =「標記:$ data」'。 – CrimsonChris

回答

0

你可以利用以下的綁定迭代地點:

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

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); 
 
});
*{ 
 
    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%; 
 
}
<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 -->

Modified example: Plunker