2016-06-13 19 views
8

Mam aplikację Rails, ostatnio zaktualizowałem ją do 5.0.0.RC1. Większość przejścia poszło gładko, ale mam problemy z nowymi Turbolinkami. W moim app I na przykład wykorzystać ten klejnot:Szyny 5 - turbolinks 5, niektóre JS nie są załadowane na renderowanie strony

gem 'chosen-rails' 

application.js Mój plik wygląda tak:

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

Kiedy klikam na link i renderowanie widoku mój chosen-query (best_in_place nie działa dobrze) nie działa przy początkowym obciążeniu, ale jeśli wykonuję intensywne odświeżanie strony, to działa. Poniżej znajduje się obraz wyniku dostaję:

How it looks now

I tu jest to obraz tego, jak chcę wyglądać:

enter image description here

Ponownie, jeśli oczekiwany wygląd działa robię twarde odświeżenie strony, ale nie po regularnym redirect_to ...

kod dla mojego rozwijanej wygląda następująco:

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

Po redirect_to to powoduje następujący kod HTML:

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

... i po ciężkim przeładowania strony mam to:

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

W pliku .coffee próbuję zainicjować chosen podobnie jak:

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

Jakieś pomysły na temat tego, co robię źle?

Odpowiedz

15

Z turbolinkami javascript jest ładowany tylko raz. W przypadku twardego odświeżania chosen działa, ponieważ cała strona jest ponownie renderowana. Po kliknięciu łącza turbolinks przejmuje kontrolę nad żądaniem i zamienia je na ajax (zamiast odświeżania całej strony). Gdy żądanie przychodzi, turbolinks zastępuje tylko stronę body, pozostawiając JS w tym samym stanie, w jakim był.

W tym celu trzeba będzie zawijać wybraną inicjatora w przypadku turbolinks:load jak tak

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

Aby uzyskać więcej informacji, zobacz https://github.com/turbolinks/turbolinks#running-javascript-when-a-page-loads

+1

Ale jest duży, ale: turbolinks przechowuje strony w pamięci podręcznej, więc należy upewnić się, że kod JavaScript jest idempotent, inaczej może skończyć się po kilku wybiera się na stronie (lub w innych przypadkach, kilka zdarzeń obsługi dołączone do elementu). Aby uzyskać więcej informacji, należy przeczytać https: //www.crossplatform.net/rails/article/should-you-disable-turbolinks/idempotent-transformation/ – maprihoda

+0

Część programów obsługi zdarzeń nie jest zbyt wielkim problemem, o ile nie dołączasz procedur obsługi do dokumentu. W przeciwnym razie przynajmniej w Turbolinks 5 jest klonowany i przywracany bez żadnych powiązanych programów obsługi itp. ... przy zachowaniu. –

0

Turbolinks i jQuery są trochę ból głowy naprawić. Zamiast wywoływania akcji na gotowym dokumencie, na stronie: ładowanie powinno działać lepiej, ponieważ z turbolinkami nie przeładowuje całego dokumentu podczas przeglądania strony. Coś takiego może zadziałać:

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

Pytanie dotyczy "nowych Turbolinków" (tj. Turbolinks 5), które faktycznie zrywają aplikacje wykorzystujące zdarzenia inne niż "turbolinks: load". Tak więc sugerowane podejście nie działa już z Railsami i Turbolinks 5. – user3670743

1

Dostałem poważnego bólu głowy, aby znaleźć sposób, aby wszystkie moje działania javascript. Najpierw wypróbuję rozwiązanie z klejnotem jquery.turbolinks, wykonując następujące wideo: How to upgrade to turbolinks 5, ale mam lightbox do wyświetlania obrazów na tej samej stronie nie działa poprawnie.Zanim więc po prostu wyłączyć Turbolinks raz na zawsze, mam więcej czasu na stronie github i próbuję to:

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

Trzeba umieścić, że na każdego linku gdzie javascript potrzebują strona przeładowania do pracy.

Może nie jest to najlepsze rozwiązanie, ale sprawia, że ​​ból głowy jest mniej bolesny.

0

Próbowałem rozwiązać to samodzielnie i znalazłem rozwiązanie, które działa dla mnie.

Mój problem polegał na tym, że miałem forum z funkcją "cytowania" do komentarzy. Z turbolinkami 5 dostałem kilka detektorów zdarzeń i skończyłem z maksymalnie czterema cytatami z tego samego komentarza w moim edytorze.

czytałem na idempotentność i znalazł rozwiązanie tutaj: How to make jQuery `bind` or `on` event handlers idempotent

stworzyłem (skopiowany) naprawdę globalną funkcję używam w moim pliku globals.coffee zdarzeń.

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

I działa.

Moje funkcje wygląda następująco:

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

Wszystkie creds za tym idzie do: Pointy którzy dostarczonego rozwiązania.

Link to turbolinks and idempotence

0

Oto, co zrobić, aby zapobiec .. Turbolinks5 ładowane wielokrotnie.

var ready = function() { 

    if ($.turboAlreadyLoaded) { 

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

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