web-dev-qa-db-fra.com

Rails 5 - turbolinks 5, certains JS non chargés sur le rendu de page

J'ai une application Rails, j'ai récemment mis à jour pour 5.0.0.RC1. La majeure partie de la transition s’est faite sans heurts, mais j’ai des problèmes avec les nouveaux Turbolinks. Dans mon application, par exemple, j'utilise ce petit bijou:

gem 'chosen-Rails'

Mon fichier application.js ressemble à ceci:

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

Lorsque je clique sur un lien et que je rends une vue, mon chosen-query (best_in_place ne fonctionne pas aussi bien) ne fonctionne pas dans le chargement initial, mais si j'effectue une actualisation complète de la page, cela fonctionne. Ci-dessous, une image du résultat obtenu:

 How it looks now

Et voici une image de ce à quoi je veux ressembler:

 enter image description here

Encore une fois, l'aspect attendu fonctionne si j'effectue une actualisation complète de la page, mais pas après un redirect_to ... normal.

Le code de ma liste déroulante ressemble à ceci:

= 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"

Après un redirect_to, il en résulte le code HTML suivant:

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

... et après une dure rechargement de page, je reçois ceci:

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

Dans un fichier .coffee, j'essaie d'initialiser chosen comme ceci:

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

Des idées sur ce que je fais mal?

10
Anders

Avec turbolinks le javascript n'est chargé qu'une fois. Sur le disque actualiser chosen fonctionne parce que la page entière est restituée. Une fois que vous avez cliqué sur un lien, turbolinks a détourné la demande et l'a convertie en une requête ajax (au lieu d'un rafraîchissement de la page complète). Une fois la demande reçue, turbolinks ne remplace que la body de la page, laissant le JS dans le même état qu’il était.

Pour résoudre ce problème, vous devrez envelopper l’initialiseur choisi dans l’événement turbolinks:load comme suit:

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

Pour plus d'informations, voir https://github.com/turbolinks/turbolinks#installing-javascript-behavior

17
patkoperwas

Voici ma solution avec Turbolinks 5 et jQuery:

  1. installez gem 'jquery-turbolinks' 

  2. ajoutez ce fichier .coffee à votre application: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee

  3. nommez-le turbolinks-compatibility.coffee 

  4. à application.js 

// = nécessite une requête
// = nécessite jquery_ujs
// = nécessite jquery.turbolinks

// = nécessite des turbolinks
// = nécessite la compatibilité avec turbolinks

9
Lowryder

J'ai très mal à la tête de trouver un moyen de faire fonctionner tout mon javascript. Tout d’abord, j’essaie la solution avec le joyau jquery.turbolinks en suivant cette vidéo: Comment passer à turbolinks 5 mais j’ai reçu un lightbox pour afficher les images de la même page ne fonctionnant pas correctement. Donc, avant de désactiver Turbolinks une fois pour toutes, je prends plus de temps sur la page github et j’essaie ceci: 

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

Vous devez mettre cela sur chaque lien où le javascript a besoin d'un rechargement de page pour fonctionner.

Ce n'est peut-être pas la meilleure solution, mais cela rend mon mal de tête moins douloureux.

2
VendezTrouvez

Turbolinks et jQuery sont un peu mal à la tête. Au lieu d'appeler une action sur le document prêt, page: charge devrait fonctionner mieux, car avec turbolinks, le document complet ne sera pas rechargé lorsque vous naviguez sur le site. Quelque chose comme ça peut marcher:

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

Voici ce que je fais .. Turbolinks5 pour empêcher chargé plusieurs fois.

var ready = function () {

   if ($.turboAlreadyLoaded) {

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

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

J'ai essayé de résoudre ce problème moi-même et j'ai trouvé une solution qui fonctionne pour moi.

Mon problème était que j'avais un forum avec une fonctionnalité de "citation" pour les commentaires. Avec turbolinks 5, j'ai eu plusieurs auditeurs d'événements et fini avec jusqu'à quatre citations du même commentaire dans mon éditeur.

J'ai lu sur idempotence et trouvé une solution ici: Comment faire des gestionnaires d'événements jQuery `bind` ou` on` idempotent

J'ai créé (copié vraiment) une fonction globale que j'utilise dans mon fichier globals.coffee pour les événements.

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

Et il fonctionne. 

Mes fonctions ressemblent à ceci:

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

Tous les crédits pour cela vont à: Pointy qui a livré la solution.

Lien vers turbolinks et idempotence

0
Björn Grunde