Используя Rails 3.1, куда вы помещаете свой «специфичный для страницы» код JavaScript? - PullRequest
386 голосов
/ 29 мая 2011

Насколько я понимаю, все ваши JavaScript объединены в один файл.Rails делает это по умолчанию, когда добавляет //= require_tree . в конец файла манифеста application.js.

Это звучит как реальный спаситель жизни, но я немного обеспокоен специфичным для страницы кодом JavaScript.Этот код выполняется на каждой странице?Последнее, что я хочу, - чтобы все мои объекты создавались для каждой страницы, когда они нужны только на 1 странице.

Кроме того, нет ли возможности для кода, который тоже конфликтует?

Или вы помещаете маленький тег script внизу страницы, который просто вызывает метод, который выполняетjavascript код для страницы?

Вам больше не нужен require.js тогда?

Спасибо

РЕДАКТИРОВАТЬ : Я ценю все ответы ..и я не думаю, что они действительно решают проблему.Некоторые из них касаются стиля и, похоже, не связаны между собой ... а другие просто упоминают javascript_include_tag ... который, как я знаю, существует (очевидно ...), но может показаться, что путь к Rails 3.1 в будущем - обернутьобъедините весь ваш JavaScript в 1 файл, а не загружайте отдельный JavaScript в нижней части каждой страницы.

Лучшее решение, которое я могу придумать, - это обернуть определенные функции в теги div с id s илиclass ы.В коде JavaScript вы просто проверяете, присутствует ли на странице id или class, и, если это так, вы запускаете связанный с ним код JavaScript.Таким образом, если динамический элемент отсутствует на странице, код JavaScript не запускается - даже если он включен в массивный файл application.js, упакованный Sprockets.

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

Я думаю, что это реальный ответ на мой вопрос.

Ответы [ 29 ]

1 голос
/ 20 июля 2012

У меня есть другое решение, которое, хотя примитив отлично работает для меня и не нуждается в каких-либо причудливых выборочных стратегиях загрузки.Включите обычную функцию готовности документа, но затем проверьте текущее расположение окон, чтобы увидеть, предназначена ли это страница для вашего javascript:

$(document).ready(function() {
   if(window.location.pathname.indexOf('/yourpage') != -1) {
          // the javascript you want to execute
   }
}

Это все еще позволяет загружать все js рельсами 3x в одном небольшом пакете, но не создает больших накладных расходов или конфликтов со страницами, для которых js не предназначен.

1 голос
/ 25 октября 2012

Переместите все ваши JS-файлы commom в подпапку, например «app / assets / javascript / global», затем в application.js измените строку //= require_tree . на //= require_tree ./global.

Теперь вы можете поместить свой JS для конкретного контроллера в корень «app / assets / javascript /», и они не будут включены в скомпилированный JS, а используются только при вызове их через = javascript_include_tag на вашем контроллере / вид.

1 голос
/ 21 октября 2012

Ответ ryguy является хорошим ответом, даже если он был понижен до отрицательных точек.

Особенно, если вы используете что-то вроде Backbone JS - каждая страница имеет свой собственный вид Backbone.Тогда у файла erb есть только одна строка встроенного javascript, который запускает правый базовый класс представления.Я считаю, что это единственная строка «склеивающего кода» и, следовательно, тот факт, что с ней все в порядке.Преимущество заключается в том, что вы можете сохранить ваше «require_tree», которое позволяет браузеру кэшировать весь javascript.

в show.html.erb у вас будет что-то вроде:

<% provide :javascript do %>
  <%= javascript_include_tag do %>
    (new app.views.ProjectsView({el: 'body'})).render();
  <% end %>
<% end do %>

, а в файле макета вам понадобится:

<%= yield :javascript %>
0 голосов
/ 03 июня 2018

Первое: удалить \\=require_tree из application.js Второе: весь ваш JS-код должен быть расположен на /app/assets/javascritpt, а весь ваш CSS-код - на /app/assets/stylesheets

0 голосов
/ 23 февраля 2015

Я объединил несколько ответов в:

Помощник приложения:

module ApplicationHelper
  def js_page_specific_include
    page_specific_js = params[:controller] + '_' + params[:action]
    if Rails.application.assets.find_asset(page_specific_js).nil?
      javascript_include_tag 'application', 'data-turbolinks-track' => true
    else
      javascript_include_tag 'application', page_specific_js, 'data-turbolinks-track' => true
    end
  end
end

layouts / application.html.haml:

 <!DOCTYPE html>
%html{lang: 'uk'}
  %head   
    = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
   bla-bla-bla
    = js_page_specific_include   
   bla-bla-bla  
0 голосов
/ 31 января 2015

Я делал это ранее, используя этот метод: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/.Супер-легкий, полагается на контроллеры, чтобы выбрать правильный JS для загрузки.

0 голосов
/ 15 октября 2013

Вот как это сделать, особенно если вам не нужно выполнять тонны библиотек для конкретной страницы, а выполнять более или менее несколько сотен строк JS.

Поскольку встраивать код Javascript в HTML совершенно нормально, просто создайте в каталоге app / views shared.js и поместите туда свой код страницы / страницы в my_cool_partial.html.erb

<script type="text/javascript"> 
<!--
  var your_code_goes_here = 0;
  function etc() {
     ...
  }
-->
</script>

Итак, откуда бы вы ни захотели, вы просто делаете:

  = render :partial => 'shared.js/my_cool_partial'

И это все, к?

0 голосов
/ 03 апреля 2012

Следуя указаниям Райана, вот что я сделал:

application.js.coffee

$ ->
    view_method_name = $("body").data("view") + "_onload"
    eval("#{view_method_name}()") if eval("typeof #{view_method_name} == 'function'")
    view_action_method_name = $("body").data("view") + "_"+$("body").data("action")+"_onload"
    eval("#{view_action_method_name}()") if eval("typeof #{view_action_method_name} == 'function'")

users.js.coffee (coffeescript для конкретного контроллера, например, контроллер: users,действие: панель инструментов)

window.users_dashboard_onload = () ->
    alert("controller action called")
window.users_onload = () ->
    alert("controller called")

application.html.haml

%body{:data=>{:view=>controller.controller_name, :action=>controller.action_name}}
0 голосов
/ 29 мая 2011

Я не пробовал это, но похоже, что верно следующее:

  • если у вас есть content_for, который является javascript (например, с настоящим javascript внутри него), sprocketsне будет знать об этом, и, следовательно, это будет работать так же, как и сейчас.

  • , если вы хотите исключить файл из большого пакета javascript, вы должны перейти в config /sprockets.yml и измените исходные файлы соответственно.Затем вы просто включите любые файлы, которые вы исключили, где это необходимо.

...