javascript - Rails 4、turbolinks 和 Coffeescript

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

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

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

我现在决定添加一个后退按钮。用法如下 - 从使用 Leaflet 的页面,用户可以单击 map 的一部分,然后转到使用 Turbolinks 的页面(如果重要的话)。在 Turbolinks 页面上,我有一个后退按钮可带您返回 Leaflet map 。

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

如果您对如何使用 Turbolinks 有建议,并且它有助于使后退按钮正常工作,我绝对不会放弃在 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 %>

传单 map /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 - 完整的 CoffeeScript 代码

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()

最佳答案

所以,有两个地方你可能会偏离正轨。第一个在这里:

$ ->
  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 (版本 <5.0,自 2016 年 2 月起已弃用),我相信自从您提到 Rails 4 以来您正在使用该版本。

无论哪种方式,将两个监听器堆叠在一起可能不是您想要做的。您可以做什么定义一个在 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 是什么,如果它是特定于 Leaflet 的,我可能无法为您提供帮助。然而,实际上有一种更具弹性的方式来编写它。

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

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

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

祝你 JavaScript 快乐! :)

关于javascript - Rails 4、turbolinks 和 Coffeescript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41244171/

相关文章:

javascript - Rails 4 应用程序在暂存/生产中缺少 application.js 和 application.css

node.js:WAITING所有线程完成

javascript - 生成随机问题

javascript - typescript : logic to covert string array into custom object

ios - Facebook SDK iOS 连接的 Rails-api 身份验证?

ruby-on-rails - Rails 4 自动生成的删除 RSpec 测试失败,即使该功能正在开发中

javascript - 在AngularJS中的指令中使用服务函数

ruby-on-rails - rails : how to check CSS or JS code code from a string?

javascript - whatwg 的 Loader 规范、动态导入建议和 &lt;script type ='module' > 之间有什么关系?

javascript - 验证后 Angular 表单重置