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:
Et voici une image de ce à quoi je veux ressembler:
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?
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
Voici ma solution avec Turbolinks 5 et jQuery:
installez gem 'jquery-turbolinks'
ajoutez ce fichier .coffee à votre application: https://github.com/turbolinks/turbolinks/blob/master/src/turbolinks/compatibility.coffee
nommez-le turbolinks-compatibility.coffee
à 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
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.
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'
})
}
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);
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.