Rails, javascript no se carga después de hacer clic en link_to helper

79

Tengo problemas para cargar mi javascript cuando utilizo un link_to helper en rieles. Cuando ingreso manualmente la URL con 'localhost: 3000 / products / new' o recargo la página, se carga el javascript, pero cuando paso por un enlace como se escribe a continuación, jQuery $(document).readyno se carga en la nueva página.

Link_to, javascript no se carga cuando hago clic en este enlace:

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

archivo products.js

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

Cualquier ayuda será muy apreciada. ¡Gracias por adelantado!

StickMaNX
fuente

Respuestas:

140

¿Estás usando Rails 4? (Descúbrelo haciendo rails -ven tu consola)

Este problema probablemente se deba a la nueva gema Turbolinks . Hace que su aplicación se comporte como una aplicación JavaScript de una sola página. Tiene algunos beneficios ( es más rápido ), pero desafortunadamente rompe algunos eventos existentes como $(document).ready()porque la página nunca se vuelve a cargar. Eso explicaría por qué JavaScript funciona cuando carga directamente la URL, pero no cuando navega a través de un link_to.

Aquí hay un RailsCast sobre Turbolinks.

Hay un par de soluciones. Puede usar jquery.turbolinks como una solución inmediata , o puede cambiar su $(document).ready()declaración para usar en su lugar el 'page:change'evento Turbolinks :

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

Alternativamente, puede hacer algo como esto para la compatibilidad con cargas de páginas regulares, así como con Turbolinks:

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

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

Si está usando Ruby on Rails> 5 (puede verificar ejecutando rails -ven la consola) use en 'turbolinks:load'lugar de'page:change'

$(document).on('turbolinks:load', ready); 
Ryan Endacott
fuente
Sí, esto es Rails 4. Lo que publicaste lo soluciona a través de link_to clicks. También hace que no funcione en cargas de páginas de URL manuales regulares, ¿hay alguna manera de hacerlo funcionar a través de ambos métodos sin duplicar mi código js? ¡Gracias!
StickMaNX
1
Hmm, eso es extraño. Creo que funcionaría para ambos. La mejor solución es probablemente usar la gema jquery.turbolinks vinculada, porque probablemente también maneja eso. Nota: no lo he usado, así que no estoy seguro. Sin embargo, parece que se vuelve 'page:load'a enlazar para llamar $(document).ready(), por lo que haría todo normalmente.
Ryan Endacott
Edité mi respuesta para crear una solución que debería funcionar sin jquery.turbolinks :)
Ryan Endacott
1
Increíble ! Me ayudó un montón !
Ajay
Editar todo el código en cada archivo js, ​​que espera que document.ready funcione como siempre, no es una opción para una aplicación de cualquier tamaño y complejidad. ¿Por qué alguien diseñaría algo que haga que document.ready no funcione como siempre lo ha hecho y lo llamaría una función? ¿Hay alguna manera de decirle a turbolinks que no rompa document.ready, o es la única opción para desinstalarlo?
JosephK
65

Tengo el mismo problema, pero jquery.turbolinks no ayudó. Noté que tengo que anular el método GET.

Ahí está mi muestra:

<%= link_to 'Edit', edit_interpreter_path(@interpreter), method: :get %>
Ice-Blaze
fuente
2
Esta fue la solución más rápida de implementar.
José Torres
1
Esto resolvió el problema, link_topero resulta que el problema real era una <script>etiqueta en línea en el pie de página. (Las etiquetas de secuencia de comandos en línea son malas con los enlaces turbo).
pobre
1
La mejor solución es eliminar los enlaces turbo, en mi opinión. Arreglar cosas que deberían "simplemente funcionar" con "soluciones alternativas" es una gran pérdida de tiempo. Podría haberme tomado una semana libre el año pasado de los arreglos de turboenlaces, solo.
JosephK
1
esto hizo mi dia !
Buena respuesta para una solución rápida, pero para una solución óptima, vea la respuesta de @RyanEndacott
dimpiax
25

Si está en los rieles 5 en lugar de 'page:change', debe usar 'turbolinks:load'así:

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

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

usuario000001
fuente
Esta y la solución de Ice-Blaze funcionaron para mí. Pero esto me gusta más porque no tengo que cambiar todos mis enlaces. (Estoy usando Rails 5)
Sean
5

También puede envolver su enlace con un div que especifique data-no-turbolink.

Ejemplo:

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

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

equn
fuente
3

Asegúrese de no tener <script>etiquetas en línea . (Las etiquetas de secuencia de comandos en línea son malas con los enlaces turbo).

hombre pobre
fuente
3

FWIW, de los documentos de Turbolinks , el evento más apropiado para capturar en lugar del $(document).readyis page:change.

page:load tiene una advertencia de que no se activa en las recargas de caché ...

Se ha cargado un nuevo elemento de cuerpo en DOM. No se activa en el reemplazo parcial o cuando se restaura una página desde la caché, para no disparar dos veces en el mismo cuerpo.

Y dado que Turbolinks solo está cambiando la vista, page:changees más apropiado.

pyepye
fuente
¡Ganador! page:loadno me estaba funcionando en las actualizaciones; Recomiendo esta solución.
TJ Biddle
0

La solución que resolvió mi problema fue agregar esta meta propiedad.

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

Esto asegura que las visitas a una determinada página siempre activarán una recarga completa.

Esto fue increíblemente útil para trabajar en una solución para resolver el problema que tenía con esto, https://github.com/turbolinks/turbolinks#reloading-when-assets-change .

Arroz Rockwell
fuente