A mi entender, todo tu JavaScript se fusiona en 1 archivo. Rails hace esto por defecto cuando se agrega //= require_tree .
a la parte inferior de suapplication.js
archivo de manifiesto.
Esto suena como un verdadero salvavidas, pero estoy un poco preocupado por el código JavaScript específico de la página. ¿Este código se ejecuta en cada página? Lo último que quiero es que todos mis objetos sean instanciados para cada página cuando solo se necesitan en 1 página.
Además, ¿no hay potencial para el código que también choca?
¿O pones un pequeño script
etiqueta en la parte inferior de la página que solo llama a un método que ejecuta el código de JavaScript para la página?
¿Ya no necesitas require.js entonces?
Gracias
EDITAR : aprecio todas las respuestas ... y no creo que realmente estén captando el problema. Algunos de ellos son sobre el estilo y no parecen relacionarse ... y otros solo mencionanjavascript_include_tag
... lo que sé que existe (obviamente ...) pero parece que el camino de Rails 3.1 en adelante es concluir todo su JavaScript en 1 archivo en lugar de cargar JavaScript individual en la parte inferior de cada página.
La mejor solución que se me ocurre es envolver ciertas características en div
etiquetas con id
s o class
es. En el código JavaScript, solo verifica si el id
o class
está en la página, y si lo está, ejecuta el código JavaScript que está asociado con él. De esta manera, si el elemento dinámico no está en la página, el código JavaScript no se ejecuta, aunque se haya incluido en el application.js
archivo masivo empaquetado por Sprockets.
Mi solución anterior tiene la ventaja de que si se incluye un cuadro de búsqueda en 8 de las 100 páginas, se ejecutará solo en esas 8 páginas. Tampoco tendrá que incluir el mismo código en 8 de las páginas del sitio. De hecho, nunca más tendrá que incluir etiquetas de script manual en su sitio en ningún otro lugar.
Creo que esta es la respuesta real a mi pregunta.
fuente
application.js
), y de hecho la referencia que proporcionó señala por qué esto es así: la descarga es la parte más lenta del proceso de ejecución de JS. Muchos archivos pequeños son más almacenables en caché que uno grande. La gente de Unholy Rails no parece darse cuenta, entonces, de que sus recomendaciones son inconsistentes con los principios a los que intentan adherirse y, por lo tanto, sus recomendaciones no deben tomarse en serio.Respuestas:
Los documentos de Asset Pipeline sugieren cómo hacer JS específicos del controlador:
Enlace a: asset_pipeline
fuente
page_specific_js = "#{params[:controller]}_#{params[:action]}"
y entonces;javascript_include_tag page_specific_js if Rails.application.assets.find_asset page_specific_js
Para los js específicos de la página, puede usar la solución Garber-Irish .
Entonces su carpeta Rails javascripts podría verse así para dos controladores: autos y usuarios:
Y los javascripts se verán así:
y markup_based_js_execution contendrá código para el objeto UTIL y en la ejecución UTIL.init lista para DOM.
Y no olvide poner esto en su archivo de diseño:
También creo que es mejor usar clases en lugar de
data-*
atributos, para el mejor CSS específico de la página. Como Jason Garber ha mencionado: los selectores CSS específicos de la página pueden volverse realmente incómodos (cuando usadata-*
atributos)Espero que esto ayude.
fuente
window.varForOneController='val'
en esta función de inicio del controlador. También gon gem puede ayudar aquí ( github.com/gazay/gon ). Puede haber otras soluciones alternativas.//= require_tree .
y usar JavaScript específico de la página. Si está tratando activamente de no hacer eso, entonces está luchando por las malas prácticas.Veo que has respondido tu propia pregunta, pero aquí hay otra opción:
Básicamente, estás asumiendo que
es requerido. No es. Siéntase libre de eliminarlo. En mi aplicación actual, la primera que estoy haciendo con 3.1.x honestamente, he creado tres archivos JS de nivel superior diferentes. Mi
application.js
archivo solo tieneDe esta manera, puedo crear subdirectorios, con sus propios archivos JS de nivel superior, que solo incluyen lo que necesito.
Las claves son:
require_tree
: Rails le permite cambiar las suposiciones que haceapplication.js
: cualquier archivo delassets/javascript
subdirectorio puede incluir directivas de preprocesador con//=
Espero que ayude y agregue algunos detalles a la respuesta de ClosureCowboy.
Sujal
fuente
//= require_tree .
con//= require_directory .
lo que puede mantener todos los archivos existentes en las que se encuentran y crean nuevos directorios para archivos específicos de la página.Otra opción: para crear archivos específicos de página o modelo, puede crear directorios dentro de su
assets/javascripts/
carpeta.Su
application.js
archivo de manifiesto principal podría configurarse para cargar sus archivosglobal/
. Las páginas específicas o grupos de páginas podrían tener sus propios manifiestos que cargan archivos de sus propios directorios específicos. Sprockets combinará automáticamente los archivos cargados porapplication.js
con los archivos específicos de su página, lo que permite que esta solución funcione.Esta técnica también se puede utilizar
style_sheets/
.fuente
Aprecio todas las respuestas ... y no creo que realmente estén llegando al problema. Algunos de ellos son sobre el estilo y no parecen relacionarse ... y otros solo mencionan
javascript_include_tag
... lo que sé que existe (obviamente ...) pero parece que el camino de Rails 3.1 en adelante es concluir todo su Javascript en 1 archivo en lugar de cargar Javascript individual en la parte inferior de cada página.La mejor solución que se me ocurre es envolver ciertas características en
div
etiquetas conid
s oclass
es. En el código javascript. Luego simplemente verifica si elid
oclass
está en la página, y si lo está, ejecuta el código de JavaScript que está asociado con él. De esta manera, si el elemento dinámico no está en la página, el código JavaScript no se ejecuta, a pesar de que se ha incluido en elapplication.js
archivo masivo empaquetado por Sprockets.Mi solución anterior tiene la ventaja de que si se incluye un cuadro de búsqueda en 8 de las 100 páginas, se ejecutará solo en esas 8 páginas. Tampoco tendrá que incluir el mismo código en 8 de las páginas del sitio. De hecho, nunca más tendrá que incluir etiquetas de script manual en su sitio en ningún lugar, excepto tal vez para precargar datos.
Creo que esta es la respuesta real a mi pregunta.
fuente
<script>
etiquetas manuales . Sí, las clases y los identificadores son parte de la respuesta, pero no tiene sentido que el usuario cargue JavaScript que esa página en particular no requiere.Me doy cuenta de que voy a llegar a esta fiesta un poco tarde, pero quería agregar una solución que he estado usando últimamente. Sin embargo, permítanme mencionar primero ...
The Rails 3.1 / 3.2 Way (No, señor. No me gusta).
Ver: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Incluyo lo siguiente en aras de la exhaustividad en esta respuesta, y porque no es una solución inviable ... aunque no me importa mucho.
"Rails Way" es una solución orientada al controlador, en lugar de estar orientada a la vista, como solicitó el autor original de esta pregunta. Hay archivos JS específicos del controlador que llevan el nombre de sus respectivos controladores. Todos estos archivos se colocan en un árbol de carpetas que NO se incluye de manera predeterminada en ninguna de las aplicaciones.js requieren directivas.
Para incluir código específico del controlador, se agrega lo siguiente a una vista.
Odio esta solución, pero está ahí y es rápida. Presumiblemente, podría llamar a estos archivos algo así como "people-index.js" y "people-show.js" y luego usar algo como
"#{params[:controller]}-index"
para obtener una solución orientada a la vista. Nuevamente, solución rápida, pero no me sienta bien.Mi manera de atributo de datos
Llámame loco, pero quiero que TODO mi JS esté compilado y minimizado en application.js cuando lo implemente. No quiero tener que recordar incluir estos pequeños archivos rezagados por todas partes.
Cargo todo mi JS en un archivo compacto, que pronto será almacenado en caché del navegador. Si una determinada parte de mi application.js necesita ser activada en una página, dejo que el HTML me lo diga, no Rails.
En lugar de bloquear mi JS a ID de elementos específicos o ensuciar mi HTML con clases de marcador, utilizo un atributo de datos personalizado llamado
data-jstags
.En cada página, yo uso - inserte el método de biblioteca JS preferido aquí - para ejecutar el código cuando el DOM haya terminado de cargarse. Este código de arranque realiza las siguientes acciones:
data-jstag
Digamos que tengo lo siguiente definido en algún lugar de mi application.js:
El evento bootstrapping aplicará las funciones
my_autosuggest_init
ymy_hint_init
contra la entrada de búsqueda, convirtiéndola en una entrada que muestra una lista de sugerencias mientras el usuario escribe, y proporcionará algún tipo de sugerencia de entrada cuando la entrada se deja en blanco y desenfocada.A menos que se etiquete algún elemento
data-jstag="auto-suggest"
, el código de sugerencia automática nunca se activa. Sin embargo, siempre está ahí, minimizado y eventualmente almacenado en caché en mi application.js para los momentos en que lo necesito en una página.Si necesita pasar parámetros adicionales a sus funciones JS etiquetadas, deberá aplicar algo de creatividad. Agregue atributos de parámetros de datos, cree algún tipo de sintaxis de parámetros o incluso utilice un enfoque híbrido.
Incluso si tengo un flujo de trabajo complicado que parece específico del controlador, simplemente crearé un archivo para él en mi carpeta lib, lo empaquetaré en application.js y lo etiquetaré con algo como 'new-thing-wizard'. Cuando mi bootstrap llegue a esa etiqueta, mi simpático y elegante asistente será instanciado y ejecutado. Se ejecuta para la (s) vista (s) de ese controlador cuando es necesario, pero no está acoplado al controlador. De hecho, si codifico correctamente mi asistente, podría proporcionar todos los datos de configuración en las vistas y, por lo tanto, volver a utilizar mi asistente más adelante para cualquier otro controlador que lo necesite.
De todos modos, así es como he estado implementando JS específicos de la página durante un tiempo, y me ha servido bien tanto para diseños de sitios simples como para aplicaciones más complejas / ricas. Con suerte, una de las dos soluciones que he presentado aquí, a mi manera o a la manera de Rails, es útil para cualquiera que se encuentre con esta pregunta en el futuro.
fuente
Esto fue respondido y aceptado hace mucho tiempo, pero se me ocurrió mi propia solución basada en algunas de estas respuestas y mi experiencia con Rails 3+.
La cartera de activos es dulce. Úsalo.
Primero, en su
application.js
archivo, elimine//= require_tree.
Luego, en su
application_controller.rb
crear un método auxiliar:Luego, en su
application.html.erb
archivo de diseño, agregue su nuevo ayudante entre los javascript existentes incluidos, con el prefijo delraw
ayudante:Voila, ahora puede crear fácilmente JavaScript específico de la vista usando la misma estructura de archivos que usa en cualquier otro lugar en rieles. ¡Simplemente pegue sus archivos
app/assets/:namespace/:controller/action.js.erb
!Espero que ayude a alguien más!
fuente
<%= raw ... %>
devuelva un 404?require_tree /
(mala)?Puede agregar esta línea en su archivo de diseño (por ejemplo, application.html.erb) para cargar automáticamente el archivo javascript específico del controlador (el que se creó cuando generó el controlador):
También puede agregar una línea para cargar automáticamente un archivo de script por acción.
Simplemente coloque los scripts de su página en un subdirectorio con el nombre del controlador. En estos archivos puede incluir otros scripts usando = require. Sería bueno crear un asistente para incluir el archivo solo si existe, para evitar una falla 404 en el navegador.
fuente
fuente
Tal vez encuentre la gema pluggable_js como la solución adecuada.
fuente
La gema LoadJS es otra opción:
fuente
La respuesta de Philip es bastante buena. Aquí está el código para que funcione:
En application.html.erb:
<body class="<%=params[:controller].parameterize%>">
Asumiendo que su controlador se llama Proyectos, eso generará:
<body class="projects">
Luego, en projects.js.coffee:
fuente
<body>
es ipso facto incorrecta. Vea mis comentarios en otra parte de esta página.JavaScripts solo se fusionan cuando le dice a Rails (Sprockets, más bien) que los combine.
fuente
//= require_tree .
?require_tree .
Suele ser una mala idea.Así es como resolví el problema del estilo: (disculpe el Haml)
De esta manera, comienzo todos los archivos .css.sass específicos de la página con:
De esta manera, puede evitar fácilmente cualquier enfrentamiento. Cuando se trata de archivos .js.coffee , puede simplemente inicializar elementos como;
Espero que esto haya ayudado a algunos.
fuente
$('#post > #edit') ->
parece ser inválido. ¿Cómo alcanzas jQuery para trabajar dentro de un alcance?= javascript_include_tag "application"
y de= javascript_include_tag params[:controller]
esta manera puedo mantener el código de JavaScript confinado sin tener que especificar un alcance dentro del archivo.También puede agrupar los js en carpetas y continuar utilizando la canalización de activos para cargar su JavaScript de forma selectiva según la página.
fuente
Estoy de acuerdo con su respuesta, para verificar si ese selector está allí, use:
(no vi a nadie agregar la solución real)
fuente
No veo una respuesta que realmente lo reúna todo y lo presente para usted. Por lo tanto, trataré de poner meleyal , sujal (a la ClosureCowboy ), la primera parte de la respuesta de Ryan e incluso la audaz declaración de Gal sobre Backbone.js ... todo junto de una manera corta y clara. Y, quién sabe, incluso podría cumplir con los requisitos de Marnen Laibow-Koser .
Ediciones de ejemplo
assets / javascripts / application.js
views / layouts / application.html.erb
views / foo / index.html.erb
assets / javascripts / foo.js
assets / javascripts / foostuff / foothis.js.coffee
Breve descripción
Elimine
//= require_tree .
de application.js y enumere solo el JS que comparte cada página.Las dos líneas que se muestran arriba en application.html.erb le dicen a la página dónde incluir application.js y su JS específico de la página.
Las tres líneas que se muestran arriba en index.html.erb le indican a su vista que busque algunos JS específicos de la página e incluirlos en una región de rendimiento nombrada llamada ": javascript" (o como quiera nombrarlo). En este ejemplo, el controlador es "foo", por lo que Rails intentará incluir "foo.js" en la región de rendimiento de javascript en el diseño de la aplicación.
Enumere su JS específico de la página en foo.js (o como se llame al controlador). Lista de bibliotecas comunes, un árbol, directorios, lo que sea.
Mantenga su JS específico de la página personalizada en un lugar donde pueda hacer referencia fácilmente, aparte de su otro JS personalizado. En este ejemplo, foo.js requiere el árbol de forraje, así que coloque su JS personalizado allí, como foothis.js.coffee .
No hay reglas estrictas aquí. Siéntase libre de mover cosas y tal vez incluso crear múltiples regiones de rendimiento de varios nombres en varios diseños si es necesario. Esto solo muestra un posible primer paso adelante. (No lo hago exactamente así dado nuestro uso de Backbone.js. También podría elegir colocar foo.js en una carpeta llamada foo en lugar de foostuff, pero aún no lo he decidido).
Notas
Puede hacer cosas similares con CSS y
<%= stylesheet_link_tag params[:controller] %>
esto está más allá del alcance de la pregunta.Si me perdí una deslumbrante práctica recomendada aquí, envíeme una nota y me adaptaré. Rails es bastante nuevo para mí y, sinceramente, hasta ahora no estoy terriblemente impresionado con el caos que trae por defecto al desarrollo empresarial y todo el tráfico que genera el programa Rails promedio.
fuente
Tengo otra solución, que aunque primitiva funciona bien para mí y no necesita ninguna estrategia de carga selectiva sofisticada. Ponga su función lista para documentos normales, pero luego pruebe la ubicación actual de Windows para ver si es la página para la que está destinado su JavaScript:
Esto todavía permite que todos los js se carguen por rails 3.x en un paquete pequeño, pero no genera demasiados gastos generales ni conflictos con las páginas para las que no está destinado el js.
fuente
La respuesta de Ryguy es una buena respuesta, a pesar de que se ha votado en puntos negativos.
Especialmente si está usando algo como Backbone JS: cada página tiene su propia vista Backbone. Luego, el archivo erb solo tiene una sola línea de JavaScript en línea que activa la clase de vista de red troncal derecha. Lo considero una sola línea de 'código de pegamento' y, por lo tanto, el hecho de que su línea está bien. La ventaja es que puede mantener su "require_tree" que le permite al navegador almacenar en caché todo el javascript.
en show.html.erb, tendrás algo como:
y en su archivo de diseño, necesitará:
fuente
Mueva todos sus archivos JS commom a una subcarpeta como 'app / assets / javascript / global' y luego, en application.js, modifique la
//= require_tree .
línea para//= require_tree ./global
.Ahora es libre de colocar su JS específico del controlador en la raíz 'app / assets / javascript /' y no se incluirán en el JS compilado, que se utilizará solo cuando los llame a través
= javascript_include_tag
de su controlador / vista.fuente
Aunque tiene varias respuestas aquí, creo que su edición es probablemente la mejor opción. Un patrón de diseño que utilizamos en nuestro equipo que obtuvimos de Gitlab es el patrón Dispatcher. Hace algo similar a lo que está hablando, sin embargo, el nombre de la página se establece en la etiqueta del cuerpo mediante rieles. Por ejemplo, en su archivo de diseño, simplemente incluya algo como (en HAML):
Entonces solo tenga un cierre y una declaración de cambio en su
dispatcher.js.coffee
archivo en su carpeta javascripts de la siguiente manera:Todo lo que necesita hacer en los archivos individuales (digamos
products.js.coffee
ologin.js.coffee
por ejemplo) es encerrarlos en una clase y luego globalizar ese símbolo de clase para que pueda acceder a él en el despachador:Gitlab tiene varios ejemplos de esto con los que es posible que desee hurgar en caso de que tenga curiosidad :)
fuente
Paloma proyecto ofrece un enfoque interesante para administrar el código JavaScript específico de la página.
Ejemplo de uso de sus documentos:
fuente
Paso 1. eliminar require_tree. en su application.js y application.css.
Paso 2. Edite su application.html.erb (por defecto de rails) en la carpeta de diseño. Agregue "params [: controller]" en las siguientes etiquetas.
Paso 3. Agregue un archivo en config / initializers / assets.rb
referencias: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/
fuente
No he probado esto, pero parece que lo siguiente es cierto:
si tiene un content_for que es javascript (por ejemplo, con javascript real dentro de él), las ruedas dentadas no lo sabrían y, por lo tanto, esto funcionaría de la misma manera que ahora.
si desea excluir un archivo del gran paquete de javascript, debe ingresar al archivo config / sprockets.yml y modificar los archivos de origen en consecuencia. Luego, simplemente incluiría cualquiera de los archivos que excluyó cuando fue necesario.
fuente
Lo hice previamente usando este método: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/ . Súper fácil, se basa en controladores para seleccionar los js adecuados para cargar.
fuente
Combiné algunas respuestas en:
Ayudante de aplicación:
diseños / application.html.haml:
fuente
Primero: eliminar
\\=require_tree
de application.js Segundo: todo su código JS debe ubicarse en/app/assets/javascritpt
y todo su código CSS debe ubicarse en/app/assets/stylesheets
fuente
Siguiendo el ejemplo de Ryan, esto es lo que he hecho:
application.js.coffee
users.js.coffee (coffeescript específico del controlador, por ejemplo, controlador: usuarios, acción: tablero)
application.html.haml
fuente
eval
) si su HTML se ve comprometido por un servidor roto o un script de usuario malicioso.Aquí le mostramos cómo hacerlo, especialmente si no tiene que ejecutar toneladas de bibliotecas para su página específica, sino solo para ejecutar unos cientos de líneas de JS más o menos.
Dado que está perfectamente bien incrustar código Javascript en HTML, solo cree en el directorio app / views shared.js y coloque allí su código específico de página / páginas dentro de my_cool_partial.html.erb
Entonces, desde donde quieras, simplemente haz lo siguiente:
Y eso es todo, k?
fuente