Каков хороший способ реализации постраничного JavaScript в Rails?

#javascript #jquery #ruby-on-rails

#javascript #jquery #ruby-on-rails

Вопрос:

Пробую что-то новое в Ruby — на каждой странице я делаю очень насыщенный материал с помощью jquery. Очевидно, что если я помещу весь jquery в application.js он очень быстро станет очень большим.

Хороший ли это подход к отложенной загрузке js-файла для конкретной страницы в конце? например:

 <script>

$(document).ready(function() {

  $.getScript("/javascripts/this_pages_scripts.js");

});
</script>
  

Есть ли способ сделать это на основе rails? Я знаю о новых файлах.js.erb и т.д. и ujs, но я все еще говорю о более специфичных для страницы js — вы знаете, инициализаторах перетаскивания, создателях диалоговых окон и т.д.

Большое вам спасибо.

Комментарии:

1. Когда вы говорите «очень быстро увеличиваться», вы, возможно, преувеличиваете. 20-30 КБ JavaScript — это много, но он не «большой», потому что он может быть отправлен в браузер сжатым примерно до 3 КБ и будет кэшироваться между запросами, если ваш сервер настроен должным образом. Вас должны беспокоить только более крупные библиотеки, такие как jQuery-UI или Google Maps, и не загружать их на страницы, которые их не используют, может помочь.

Ответ №1:

Есть два способа, которые я использую:

Для крошечных, тривиальных скриптов, которые просто добавляют немного привлекательности, я часто включаю их встроенными в шаблон, который они изменяют (точно так же, как вы показали), потому что мне легче отслеживать этот способ.

Для всего, что больше одной или двух маленьких строк, я делаю это незаметно, но загружаю с помощью content_for

Макет моего приложения выглядит следующим образом (в HAML):

 = javascript_include_tag 'jquery.144.min','rails','jquery.tools','application'
= yield :scripts
  

Важная часть заключается в yield :scripts . Затем на странице, где мне нужен javascript, я делаю:

 - content_for :scripts do
  = javascript_include_tag 'photo_form'
  

Это загружает javascript в заголовок, но только в том случае, если показан данный шаблон. content_for отправляет данные в yield метод с соответствующим именем.

Подобный блок yield можно вставить куда угодно — у меня также есть такой непосредственно перед закрывающим тегом body. Yield / content_for действительно удобен.

Обратите внимание, как указал тэдман в комментариях, все, что не обязательно загружать в head, должно быть загружено в конце страницы.

И последнее, о чем следует помнить, если у вас есть что-то более сложное, вы также можете использовать переменные экземпляра между вашими шаблонами и представлением вашего приложения. Например, у меня есть панель меню в моем приложении, которая находится в макете приложения. Итак, иногда я хочу вызвать контекстно-зависимую кнопку или дополнительный ряд кнопок только на определенных страницах.

В моем макете приложения я вызываю частичное отображение меню, код меню выглядит следующим образом:

 #menubar (normal menu stuff)
  - if @special_menu
    #special_menu
  

Итак, тогда в любом шаблоне вы можете сделать:

 - @special_menu = true
  

… и для этой страницы появится указанное меню. Вы также можете сделать это в controller actions, у меня есть один контроллер, где я добавил фильтр before, который устанавливает для одного из флагов меню значение true. Вы могли бы сделать то же самое для любого сложного набора javascript-материалов, которые вы, возможно, захотите включить условно.

Большинство из этих идей я почерпнул из просмотра этого railscast: http://railscasts.com/episodes/30-pretty-page-title

Вам стоит взглянуть!

Комментарии:

1. По возможности файлы JavaScript следует загружать в документе в самом конце, чтобы они не задерживали рендеринг страницы. Аналитика должна быть последней, например, перед закрытием <body> тега. jQuery необходимо загружать заранее, как и все остальное, что используется $(document).ready(...) по очевидным причинам.

Ответ №2:

Установите символ для представления имени файла в вашем заголовке и вызовите его в контроллере

 @script = "prototype"
  

Затем в представлении:

 <%= javascript_include_tag @script %>
  

Или загрузить несколько

 @scripts = ["prototype", "dropdown"]
  

Затем

 <% @scripts.each do |s| %>
  <%= javascript_include_tag s %>
<% end amp;>
  

Комментарии:

1. Тогда просто сделайте его другим в каждом контроллере

2. На самом деле это не дает ответа на основную часть вопроса о том, что такое соглашение Rails для структурирования вашего javascript по файлам. И, кстати, вы можете использовать оператор splat для расширения массива до аргументов типа js = %w{foo bar}; javascript_include_tag *js .

Ответ №3:

Я лично использую RequireJS и пользовательскую библиотеку обнаружения функций для решения этой проблемы.

Затем у меня есть одна строка для включения скрипта requirejs и его data-main атрибута на моей странице layout / master / shared view. (Я не знаком с rails как таковым, но это то же самое с любым другим MVC).

Я написал хороший ответ об этом где-то в другом месте. Возможно, вы сможете его найти.