【问题标题】:Rails 4, turbolinks, and coffeescriptRails 4、turbolinks 和 coffeescript
【发布时间】:2016-12-20 14:04:12
【问题描述】:

如果我有点困惑,请原谅我,我正在冒险进入我编程的新领域,并且边走边学。我正在努力解决的基本概念:

在我的 Rails 4 应用程序中,我使用 Leaflet(一个用于映射的 JS 库)并调用我自己的一些代码。长话短说,我无法让 Leaflet 和 Turbolinks 一起很好地发挥作用,所以对于我网站中需要 Leaflet 的页面,我禁用了 Turbolinks,另外我正在加载页面特定的 Coffeescript。

我现在决定要添加一个后退按钮。用法是这样的——从使用 Leaflet 的页面,用户可以单击地图的一部分并被带到使用 Turbolinks 的页面(如果重要的话)。在 Turbolinks 页面中,我有一个返回按钮,可将您带回 Leaflet 地图。

但是,当我返回 Leaflet 页面时,我的咖啡脚本要么没有运行,要么运行时间错误(我遇到了几个第一次运行时不存在的错误)。我猜我需要在 Coffeescript 的开头添加另一个事件或选择一个不同的事件,但我不确定它应该是什么。

如果您有关于如何使其工作的建议并且有助于使后退按钮正常工作,我绝不会拒绝在 Leaflet 页面上使用 Turbolinks。 :)

_navbar.html.erb

<li><%= link_to("By grid", grid_path, data: {turbolinks: false}) %></li>

grid.html.erb

... code for layout goes here ...
<% content_for :header do %>
  <%= javascript_include_tag "leaflet" %>
<% end %>
<% content_for :javascript do %>
  <%= javascript_include_tag "leaflet-maps/#{filename}" %>
<% end %>

leaflet-maps/grid.coffee

$ ->
  document.addEventListener 'page:restore', ->
    app.init()
    return
... rest of coffeescript goes here ...
... here is how the link is getting called
  layer.on 'click', (e) ->
    window.location.href='/show?grid='+feature.id
    return

show.html.erb

<%= link_to "Back", :back %>

更新

grid.coffee - 完整的咖啡脚本代码

ready = ->
#--------------------------------------------------
# Build tooltip with plant name 
#--------------------------------------------------
  onEachFeature = (feature, layer) ->
    if feature.properties and feature.properties.grid_name
      layer.bindTooltip feature.properties.grid_name
      layer.on 'click', (e) ->
        window.location.href='/show?grid='+feature.id
        return
    return

#--------------------------------------------------
# Variables
#--------------------------------------------------
  L.Icon.Default.imagePath = '/assets'
  gridStyle = {
    "color": "#ff7800",
  }
  neCorner = L.latLng([47.635103, -122.320525])
  swCorner = L.latLng([47.634083, -122.321129])


#--------------------------------------------------
# Set view and load Google Maps
#--------------------------------------------------
  map = L.map("map", zoomSnap: .25)
  map.fitBounds([swCorner, neCorner])
  map.invalidateSize(false)
  map.options.maxZoom = 22
  map.options.bounceAtZoomLimits = true
  googleLayer = L.gridLayer.googleMutant(type: 'roadmap').addTo(map)
  map.addLayer googleLayer

#--------------------------------------------------
# Get Ajax data
#--------------------------------------------------
  $.ajax
    dataType: 'text'
    url: 'grid.json'
    success: (data) ->
      L.geoJSON(JSON.parse(data), style: gridStyle, onEachFeature: onEachFeature ).addTo map
    error: ->
      alert "Failed to load AJAX data"

document.addEventListener 'turbolinks:load', ready()
document.addEventListener 'DOMContentLoaded', ready()

【问题讨论】:

    标签: javascript ruby-on-rails-4 coffeescript leaflet turbolinks


    【解决方案1】:

    因此,有两个地方您可能会偏离轨道。第一个在这里:

    $ ->
      document.addEventListener 'page:restore', ->
        app.init()
    

    这是说...“当网页发出 DOMContentLoaded 事件时,当其他东西发出 page:restore 事件时,运行我的 JavaScript 代码。”

    让我们从DOMContentLoaded 开始。这是浏览器默认发出的事件,jQuery 框架使用它来触发事件侦听器。 You can read more about jQuery's .ready() function here.

    page:restore 事件不是标准发出的事件,而是 a custom event used in Turbolinks Classic(版本

    无论哪种方式,将两个侦听器堆叠在一起可能不是您想要做的。你可以做什么定义一个在readypage:restore上运行的函数...

    function ready() {
       // All of the setup you want to do...
    }
    
    document.addEventListener("turbolinks:load", ready());
    document.addEventListener("DOMContentLoaded", ready());
    

    (对不起,我知道你在写 CoffeeScript。那不是我的问题。我希望我的 JavaScript 没问题...)

    这是一个。我看到了另一个改进的机会。

    layer.on 'click', (e) ->
    

    你的意思是“当文档被加载时,监听layer对象的点击,然后做这件事。”

    我不确定layer 是什么,如果它是特定于传单的,我可能无法为您提供帮助。然而,实际上有一种更有弹性的方式来写这个。

    $(document).on("click","layer", function() {
      // do things with the layer
    });
    

    这可能看起来相同,但有细微的差别。它的意思是“每当我点击文档时,如果我碰巧点击了一个图层,请执行此操作。”

    这更有弹性,因为您的 JavaScript 行在运行时可以始终找到document。如果您的 layer 在该行代码运行时尚未呈现,则它永远不会捕获这些点击。

    快乐的JavaScript! :)

    【讨论】:

    • 这些都是非常有用的 cmets。 :) 我检查了我的代码,结果发现我使用的是 TurboLinks 5。那么有更好的方法吗?另外,我添加了完整的咖啡脚本代码,因为我不确定我是否了解如何更改图层。这是层的传单文档的link(以防他们有帮助)。