简体   繁体   English

Rails 5 - turbolinks 5,页面渲染时未加载某些 JS

[英]Rails 5 - turbolinks 5,some JS not loaded on page render

I have a Rails app, I recently updated to 5.0.0.RC1 .我有一个 Rails 应用程序,我最近更新到5.0.0.RC1 Most of the transition went smooth, but I'm having some trouble with the new Turbolinks.大多数过渡都很顺利,但我在使用新的 Turbolinks 时遇到了一些麻烦。 In my app I for example use this gem:例如,在我的应用程序中,我使用这个 gem:

gem 'chosen-rails'

My application.js file looks like this:我的application.js文件如下所示:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require best_in_place
//= require tether
//= require bootstrap
//= require chosen-jquery
//= require_tree .
//= require turbo links

When I click on a link and render a view my chosen-query ( best_in_place doesn't work as well) doesn't work in the initial load, but if I make a hard refresh of the page then it works.当我单击链接并呈现视图时,我chosen-querybest_in_place也不起作用)在初始加载中不起作用,但是如果我对页面进行了硬刷新,则它起作用了。 Below is an image of the result I'm getting:下面是我得到的结果的图像:

现在的样子

And here is an image of how I want it to look:这是我希望它看起来如何的图像:

在此处输入图片说明

Again, the expected look works if I make a hard refresh of the page, but not after a regular redirect_to ...同样,如果我对页面进行硬刷新,预期的外观会起作用,但不是在常规的redirect_to ...

The code for my dropdown looks like this:我的下拉菜单的代码如下所示:

= select_tag :screen, options_from_collection_for_select(@screens, "id",  "name"), id: "screen-selection", prompt: "Jump to screen", class: 'form-control  chosen-select', style: "max-width: 250px !important"

After a redirect_to it results in the following HTML:redirect_to它会生成以下 HTML:

<select name="screen" id="screen-selection" class="form-control chosen-select"  style="max-width: 250px !important">[...]</select>

... and after a hard page reload I get this: ...在重新加载硬页面后,我得到了这个:

<select name="screen" id="screen-selection" class="form-control chosen-select"  style="max-width: 250px !important; display: none;">[...]</select>

<div class="chosen-container chosen-container-single" style="width: 190px;" title="" id="screen_selection_chosen"><a class="chosen-single"><span>Jump to screen</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off"></div><ul class="chosen-results"><li class="active-result result-selected" data-option-array-index="0" style="">Jump to screen</li><li class="active-result" data-option-array-index="1" style="">tests</li></ul></div></div>

In a .coffee file I try to initialise chosen like this:.coffee文件中,我尝试像这样初始化chosen

# enable chosen js
$('#screen-selection').chosen({
  width: '190px'
})

Any ideas on what I'm doing wrong?关于我做错了什么的任何想法?

With turbolinks the javascript is only loaded once.使用 turbolinks,javascript 只加载一次。 On the hard refresh chosen works because the entire page is re-rendered.chosen的硬刷新上,因为整个页面都被重新渲染。 Once you click a link, turbolinks hijacks the request and turns it into an ajax one (instead of a full page refresh).单击链接后,turbolinks 会劫持该请求并将其转换为 ajax 请求(而不是整页刷新)。 Once the request comes in, turbolinks only replaces the body of the page, leaving the JS in the same state it was.一旦请求进来,turbolinks 只会替换页面的body ,让 JS 保持原来的状态。

To fix this you will need to wrap your chosen initializer in the turbolinks:load event like so要解决此问题,您需要像这样将您选择的初始化程序包装在turbolinks:load事件中

$(document).on('turbolinks:load', function() {
  $('#screen-selection').chosen({
    width: '190px'
  })
})

For more information, see https://github.com/turbolinks/turbolinks#installing-javascript-behavior有关更多信息,请参阅https://github.com/turbolinks/turbolinks#installing-javascript-behavior

Here is my solution with Turbolinks 5 and jQuery:这是我使用 Turbolinks 5 和 jQuery 的解决方案:

  1. install gem 'jquery-turbolinks'安装 gem 'jquery-turbolinks'

  2. add this .coffee file to your app: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee将此 .coffee 文件添加到您的应用程序: https : //github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

  3. name it turbolinks-compatibility.coffee将其命名为 turbolinks-compatibility.coffee

  4. at application.js在 application.js

//=require jquery //=需要jquery
//=require jquery_ujs //=需要 jquery_ujs
//=require jquery.turbolinks //=需要 jquery.turbolinks

//=require turbolinks //=需要涡轮链接
//=require turbolinks-compatibility //=需要turbolinks-compatibility

I got a serious headache to find a way to make all my javascript work.我很头疼地想找到一种方法来让我的所有 javascript 工作。 First i try the solution with the gem jquery.turbolinks by following this video: How to upgrade to turbolinks 5 but i got lightbox for showing the images in the same page not working properly.首先,我按照以下视频尝试使用 gem jquery.turbolinks 的解决方案:如何升级到 turbolinks 5但我得到了用于在同一页面中显示图像的灯箱无法正常工作。 So before just disable Turbolinks once and for all, i take more time on the github page and i try this:因此,在一劳永逸地禁用 Turbolinks 之前,我在github页面上花费了更多时间,然后尝试以下操作:

<div data-turbolinks="false">
  <a href="/">Disabled</a>
</div>

You need to put that on each link where the javascript need a page reload to work.您需要将其放在 javascript 需要重新加载页面才能工作的每个链接上。

Maybe its not the best solution, but that make my headache less painful.也许它不是最好的解决方案,但这让我的头痛不那么痛苦。

Turbolinks and jquery are kinda headache. Turbolinks 和 jquery 有点头疼。 Instead of calling an action on document ready, on page:load should work better, 'cause with turbolinks, it doesn't reload the entire documment when you browse the website.与其在文档就绪时调用操作,在 page:load 上应该工作得更好,因为使用 turbolinks,当您浏览网站时,它不会重新加载整个文档。 Something like this may work:像这样的事情可能会奏效:

$(document).on('page:load', function() {
  $('#screen-selection').chosen({
    width: '190px'
  })
}

I tried to solve this myself and found a solution that works for me.我试图自己解决这个问题,并找到了一个适合我的解决方案。

My problem was that i had a forum with a "quote" functionality for comments.我的问题是我有一个带有“引用”功能的论坛以供评论。 With turbolinks 5 i got several event listeners and ended up with up to four quotes from the same comment in my editor.使用 turbolinks 5,我得到了几个事件监听器,最后在我的编辑器中得到了来自同一条评论的最多四个引号。

I read upon idempotence and found a solution here: How to make jQuery `bind` or `on` event handlers idempotent我阅读了幂等性并在这里找到了一个解决方案: How to make jQuery `bind` or `on` event handlers idempotent

I created (copied really) a global function that i use in my globals.coffee file for events.我创建了(真的复制了)一个全局函数,我在我的 globals.coffee 文件中使用它来处理事件。

$.fn.event = (name, fn) ->
  @unbind(name).bind name, fn

And it works.它有效。

My functions looks like this:我的功能如下所示:

$('.quote').event 'click', (event) ->
 do something 

All creds for this goes to: Pointy who delivered the solution.这一切都归功于:提供解决方案的Pointy

Link to turbolinks and idempotence 链接到 turbolinks 和幂等性

Here's what I do.. Turbolinks5 to prevent loaded multiple times.这就是我所做的.. Turbolinks5 以防止多次加载。

var ready = function () {

   if ($.turboAlreadyLoaded) {

      $('#screen-selection').chosen({
        width: '190px'
      })
   }
$.turboAlreadyLoaded = true;

}
$(document).ready(ready);
$(document).on("turbolinks:load", ready);

I tried to solve this myself and found a solution that works for me.我试图自己解决这个问题,并找到了一个适合我的解决方案。 I also hope Helpfully for others.我也希望对其他人有帮助。

(function () {
    $('#screen-selection').chosen({
        width: '190px'
    })
})();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM