Coffeescript类的行为不符合预期
Coffeescript Class not Behaving as Expected
标题名称不好,抱歉。不知道该怎么总结
我试图使用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()
函数的效果和副作用感到困惑。如果本质上是相同的行为,为什么在不同的文件中表现不同呢?
知道为什么这是失败的(默默地)吗?这让我有点抓狂。
我相信你在地图属性中使用@
是导致问题的原因。不是访问OpenLayersMap
的当前实例,而是调用OpenLayersMap
上的静态属性mapId
。例如:
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
。
- “;Stub对象”;对象不符合检查点's条件
- 使用 jQuery 检查文本可见性 .包含代码的行为不符合预期
- Javascript setSelectionRange 在单元测试中的行为不符合预期
- DOM元素的行为不符合预期
- Javascript动画的行为不符合预期
- 谷歌图表与表给予“;[对象对象]不符合控制规范”;错误
- Chrome 中的 Array.prototype.splice - 不符合规范
- 获取集合中不符合条件的所有文档
- 标头不符合 100% 宽度
- 粘性导航栏在 jsfiddle 上工作,但在本地主机上不符合预期
- 页面视图不符合预期,HTML 未显示,页面为空白
- Javascript clearInterval 和 setInterval() 的行为不符合预期
- jQuery Clone() 在页面中的行为不符合 asp.net
- JavaScript 如果文本输入不符合参数,则阻止文本输入
- event.stopPropagation();行为不符合预期
- 为什么正则表达式模式不符合 javascript 数据类型的条件
- 表格下拉选择不符合Div
- 从没有'不符合Regex规则
- $(window).滚动在if语句内部执行,即使它没有't不符合条件
- 使用不符合noconflict的外部JavaScript文件