错误的标题名称,抱歉。不确定如何总结这一点。
我尝试使用OpenLayers地图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()
函数的效果和副作用感到困惑。如果它的行为基本相同,为什么它会在不同的文件中表现不同?
为什么会失败(默默地)的任何想法?它让我有点疯狂。
答案 0 :(得分:2)
我相信您在地图属性中使用@
会导致问题。您没有访问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")
答案 1 :(得分:2)
我完全同意Kyle Needham's explanation,但我想提出另一种解决方案。
要修复代码,只需将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
。