Rails, Javascript wird nach dem Klicken durch link_to helper nicht geladen

78

Ich habe Probleme beim Laden meines Javascript, wenn ich einen link_to-Helfer in Rails verwende. Wenn ich entweder die URL manuell mit 'localhost: 3000 / products / new' eingebe oder die Seite neu lade, wird das Javascript geladen, aber wenn ich über einen Link gehe, wie unten beschrieben, wird die jQuery $(document).readynicht auf die neue Seite geladen.

Link_to, Javascript wird nicht geladen, wenn ich auf diesen Link klicke:

<%= link_to "New Product", new_product_path %>

products.js Datei

$(document).ready(function() {
    alert("test");
});

Jede Hilfe wäre sehr dankbar. Danke im Voraus!

StickMaNX
quelle

Antworten:

139

Verwenden Sie Rails 4? (Finden Sie es heraus, indem Sie es rails -vin Ihrer Konsole tun )

Dieses Problem ist wahrscheinlich auf das neu hinzugefügte Juwel Turbolinks zurückzuführen . Dadurch verhält sich Ihre Anwendung wie eine einseitige JavaScript-Anwendung. Es hat ein paar Vorteile ( es ist schneller ), aber es bricht leider einige bestehende Ereignisse, wie zum Beispiel, $(document).ready()weil die Seite nie neu geladen wird. Das würde erklären, warum JavaScript funktioniert, wenn Sie die URL direkt laden, aber nicht, wenn Sie durch a zu ihr navigieren link_to.

Hier ist ein RailsCast über Turbolinks.

Es gibt ein paar Lösungen. Sie können jquery.turbolinks als Drop-In-Fix verwenden oder Ihre $(document).ready()Anweisung so ändern , dass stattdessen das Turbolinks- 'page:change'Ereignis verwendet wird:

$(document).on('page:change', function() {
    // your stuff here
});

Alternativ können Sie aus Gründen der Kompatibilität mit regulären Seitenladevorgängen sowie Turbolinks Folgendes tun:

var ready = function() {
    // do stuff here.
};

$(document).ready(ready);
$(document).on('page:change', ready);

Wenn Sie Ruby on Rails> 5 verwenden (Sie können dies überprüfen, indem Sie es rails -vin der Konsole ausführen), verwenden Sie 'turbolinks:load'stattdessen anstelle von'page:change'

$(document).on('turbolinks:load', ready); 
Ryan Endacott
quelle
Ja, dies ist Rails 4. Was Sie gepostet haben, behebt es durch link_to-Klicks. Es funktioniert auch nicht beim normalen manuellen Laden von URL-Seiten. Gibt es eine Möglichkeit, beide Methoden zu verwenden, ohne meinen js-Code zu duplizieren? Vielen Dank!
StickMaNX
1
Hmm, das ist seltsam. Ich würde denken, dass es für beide funktionieren würde. Die beste Lösung ist wahrscheinlich, das verknüpfte Juwel jquery.turbolinks zu verwenden, da es wahrscheinlich auch damit umgeht. Hinweis: Ich habe es nicht verwendet, daher bin ich mir nicht sicher. Es sieht so aus, als würde es 'page:load'den Anruf erneut binden $(document).ready(), sodass Sie einfach alles wie gewohnt tun würden.
Ryan Endacott
Ich habe meine Antwort bearbeitet, um eine Lösung zu finden, die ohne jquery.turbolinks funktionieren sollte :)
Ryan Endacott
1
Genial ! es hat mir sehr geholfen!
Ajay
Das Bearbeiten des gesamten Codes in jeder js-Datei, bei dem erwartet wird, dass document.ready wie immer funktioniert, ist keine Option für eine App beliebiger Größe und Komplexität. Warum sollte jemand etwas entwerfen, das document.ready nicht so funktioniert wie immer, und das eine Funktion nennen? Gibt es eine Möglichkeit, Turbolinks anzuweisen, das Dokument nicht zu beschädigen. Bereits - oder gibt es die einzige Möglichkeit, es zu deinstallieren?
JosephK
65

Ich habe das gleiche Problem, aber jquery.turbolinks hat nicht geholfen. Mir ist aufgefallen, dass ich die GET-Methode überschreiben muss.

Da ist meine Probe:

<%= link_to 'Edit', edit_interpreter_path(@interpreter), method: :get %>
Ice-Blaze
quelle
2
Dies war die am schnellsten zu implementierende Lösung.
Jose Torres
1
Dies löste das Problem, stellte sich link_tojedoch heraus, dass das eigentliche Problem ein Inline- <script>Tag in der Fußzeile der Seite war. (Inline-Skript-Tags sind mit Turbolinks schlecht).
armer Mann
1
Die beste Lösung ist, Turbolinks zu entfernen, imo. Dinge zu reparieren, die mit "Workarounds" "nur funktionieren" sollten, ist ein großer Zeitkiller. Ich hätte mir letztes Jahr allein eine Woche frei nehmen können, wenn ich Turbolinks repariert hätte.
JosephK
1
das machte meinen Tag!
Gute Antwort für schnelle Lösung, aber für eine optimale Lösung siehe die Antwort von @RyanEndacott
Dimpiax
25

Wenn Sie auf Schienen 5 sind 'page:change', sollten Sie stattdessen Folgendes verwenden 'turbolinks:load':

$(document).on('turbolinks:load', function() {
  // Should be called at each visit
})

Quelle: https://stackoverflow.com/a/36110790

user000001
quelle
Dies und die Lösung von Ice-Blaze haben beide für mich funktioniert. Aber das gefällt mir am besten, da ich nicht alle meine Links ändern muss. (Ich benutze Rails 5)
Sean
5

Sie können Ihren Link auch mit einem div umschließen, das data-no-turbolink angibt.

Beispiel:

<div id="some-div" data-no-turbolink>
    <a href="/">Home (without Turbolinks)</a>
</div>

Quelle: https://github.com/rails/turbolinks

Gl
quelle
3

Stellen Sie sicher, dass Sie keine Inline- <script>Tags haben. (Inline-Skript-Tags sind mit Turbolinks schlecht).

armer Mann
quelle
3

FWIW, von den Turbolinks docs das geeignetere Ereignis zu erfassen , anstatt das $(document).readyist page:change.

page:load hat eine Einschränkung, die beim erneuten Laden des Caches nicht ausgelöst wird ...

Ein neues Body-Element wurde in das DOM geladen. Wird beim teilweisen Ersetzen oder beim Wiederherstellen einer Seite aus dem Cache nicht ausgelöst, um nicht zweimal auf demselben Textkörper ausgelöst zu werden.

Und da Turbolinks nur die Ansicht wechselt, page:changeist dies angemessener.

Pyepye
quelle
Gewinner! page:loadarbeitete nicht für mich an Erfrischungen; Ich empfehle diese Lösung.
TJ Biddle
0

Die Lösung, die mein Problem löste, war das Hinzufügen dieser Meta-Eigenschaft.

<meta name="turbolinks-visit-control" content="reload">

Dies stellt sicher, dass Besuche auf einer bestimmten Seite immer ein vollständiges Neuladen auslösen.

Dies war unglaublich nützlich, um an einer Lösung zu arbeiten, um das Problem zu lösen, das ich damit hatte: https://github.com/turbolinks/turbolinks#reloading-when-assets-change .

Rockwell Reis
quelle