[英]Coffeescript Class not Behaving as Expected
標題名稱錯誤,對不起。 不太確定如何對此進行總結。
我正在嘗試使用OpenLayers map API將帶有許多標記的地圖打印到頁面上。 我有可用的代碼,但是當我嘗試將其移至單獨的Coffeescript類時,它會靜默失敗。 以下代碼有效:
fromProjection = new OpenLayers.Projection("EPSG:4326") # Transform from WGS 1984
toProjection = new OpenLayers.Projection("EPSG:900913") # to Spherical Mercator Projection
mapnik = new OpenLayers.Layer.OSM()
markers = new OpenLayers.Layer.Markers("Markers")
map = new OpenLayers.Map("john-muir-trail-map")
markerCoordinates = -> $("\#john-muir-trail-data").data('markers').split('+')
paint = ->
map.addLayer(mapnik)
map.addLayer(markers)
for pair in markerCoordinates()
coords = pair.split(":")
pos = new OpenLayers.LonLat(coords[1], coords[0]).transform( fromProjection, toProjection )
markers.addMarker(new OpenLayers.Marker(pos))
map.setCenter(pos, 8)
paint()
它依賴於兩個存在的div(一個ID為“ john-muir-trail-map”,另一個ID為“ john-muir-trail-data”和一些標記數據)。 當上面的代碼在我的主要.coffee
文件中時,它工作得很好。
但是 ,當我嘗試通過將地圖代碼移到一個單獨的OpenLayerMap Coffeescript類中來對事物進行模塊化時,不會出現任何錯誤,但這是行不通的。 這就是我所做的。 (我很確定我正確地包含了這些東西。該類以及它的方法和屬性都可以從我的主文件中獲得):
class OpenLayersMap
constructor: (mapId) ->
@mapId = mapId
fromProjection: new OpenLayers.Projection("EPSG:4326") # Transform from WGS 1984
toProjection: new OpenLayers.Projection("EPSG:900913") # to Spherical Mercator Projection
mapnik: new OpenLayers.Layer.OSM()
markers: new OpenLayers.Layer.Markers("Markers")
map: new OpenLayers.Map("#{@mapId}-map")
markerCoordinates: -> $("\##{@mapId}-data").data('markers').split('+')
paint: ->
@map.addLayer(@mapnik)
@map.addLayer(@markers)
for pair in @markerCoordinates()
coords = pair.split(":")
pos = new OpenLayers.LonLat(coords[1], coords[0]).transform( @fromProjection, @toProjection )
@markers.addMarker(new OpenLayers.Marker(pos))
@map.setCenter(pos, 8)
window.OpenLayersMap = OpenLayersMap
然后,我在先前的文件中將其命名為:
map = new OpenLayersMap('john-muir-trail')
map.paint()
我認為OpenLayers圍繞投影等的細節並不重要。 重要的是, mapId
正在傳入並正確使用,如果我將調試器扔到paint()
函數中,則該調試器將被命中,並且那時所有可用的屬性對我來說都是很好的。 正確包含了該類,等等。 但是 ,沒有地圖被繪制。
我有Ruby背景,我想我對paint()
函數的效果和副作用感到困惑。 如果它本質上是相同的行為,為什么在不同的文件中表現不同?
有任何想法為什么會失敗(無聲)? 它讓我有點發瘋。
我相信您在地圖屬性中使用@
會導致此問題。 而不是訪問的當前實例的OpenLayersMap
您呼叫的靜態屬性mapId
上OpenLayersMap
。 例如:
map: new OpenLayers.Map("#{@mapId}-map")
將編譯為:
OpenLayersMap.prototype.map = new OpenLayers.Map("" + OpenLayersMap.mapId + "-map");
您將需要使map
成為訪問構造函數中設置的@mapId
的方法。
map: -> new OpenLayers.Map("#{@mapId}-map")
我完全同意Kyle Needham的解釋 ,但我想提出另一種解決方案。
要修復代碼,只需將map
分配從類原型移至其構造函數:
class OpenLayersMap
constructor: (mapId) ->
@mapId = mapId
@map = new OpenLayers.Map("#{@mapId}-map")
您還應該考慮從fromProjection
, toProjection
, mapnik
和markers
定義移至構造函數。
在您當前的實現中, OpenLayersMap
所有實例將具有相同的markers
值,例如:
l1 = new OpenLayersMap 'l1'
l2 = new OpenLayersMap 'l2'
l1.markers is l2.markers # true, meaning they are the same object
因此,通過l1.markers
您不僅會影響OpenLayersMap
類的所有現有實例,還將改變其原型。
這意味着,通過在OpenLayersMap
類的任何實例中更改這四個屬性中的任何一個,您將對所有其他實例進行相同的更改。
如果所有這些類( Projection
, Layer
和Markers
)都是不可變的(即提供一堆幫助器,但是不保持任何狀態),那么您的實現是正確的,但是我懷疑有人會費心將一堆無狀態的幫助器包裝到類中。
因此,考慮將代碼更改為:
class OpenLayersMap
constructor: (mapId) ->
@mapId = mapId
@map = new OpenLayers.Map "#{@mapId}-map"
@fromProjection = new OpenLayers.Projection "EPSG:4326"
@toProjection = new OpenLayers.Projection "EPSG:900913"
@mapnik = new OpenLayers.Layer.OSM()
@markers = new OpenLayers.Layer.Markers "Markers"
在這種情況下,每個OpenLayersMap
實例將具有其自己的fromProjection
, toProjection
, mapnik
和markers
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.