我将应用程序迁移到了Ruby on Rails 5(v5.2.2),并且试图使用Turbolinks 5(v5.2.0)。
在我的应用程序中,我查看了包含
// 没有成功。
我应该如何重构以上代码以使其能够与Turbolinks一起正常使用?
奖金:
Turbolinks 文档说:您可以使用内联主体脚本来设置每页JavaScript状态或引导客户端模型。 “每页JavaScript状态”和“引导客户端模型”是什么意思?
答案 0 :(得分:1)
如果您的内联脚本包含在<body>
的底部(或者它们没有立即操纵DOM),那么您也许可以从$(document).ready…
函数中删除代码,并使它们按预期工作。
通常不建议使用内联脚本,因为传统上它们指示代码仅在包含它的页面上运行,并且当用户离开时,任何事件侦听器都将被自动销毁。但是,在Turbolinks应用程序中并非如此。如果您在嵌入式脚本中添加事件监听器(但不要删除它),它将继续监听并在后续页面加载中运行。通过以这种方式设置turbolinks:load
事件监听器可以发现,处理程序在随后的页面加载时触发,并且在重新访问第一页时,再次添加了事件监听器,从而导致重复调用。
关于设置“每页JavaScript状态”和“引导客户端模型”,假设您有一个日历页面,希望使用某些JavaScript进行增强。您可能有一个Calendar
JavaScript类来处理此问题,因此您可以包括以下内容以使用一些JSON引导它:
<script>new Calendar(<%= @calendar.to_json %>)</script>
(请记住,在Calender
类中设置的所有添加的事件侦听器都可能在某个时候被销毁,例如turbolinks:before-cache
)。
这说明了这个想法,但是在这种情况下,更好的方法可能是建立一个查找日历元素的系统,然后在DOM中实例化它们。例如:
<div data-component="calendar" data-props="<%= @calendar.to_json %>">…</div>
然后在您的JavaScript中(包含在应用程序捆绑包中):
;(function () {
var calendar
$(document).on('turbolinks:load', function () {
var $el = $('[data-component=calendar]')
if ($el.length) calendar = new Calender($el.data('props'))
})
$(document).on('turbolinks:before-cache', function () {
if (calendar) {
calendar.destroy() // to teardown any event listeners etc
calender = null
}
})
})()
这种方法可以推广,在这里我已经完成了一个实现:https://stackoverflow.com/a/44057187/783009
希望有帮助!