Используя 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 ]

5 голосов
/ 02 мая 2013

Gem LoadJS является еще одним вариантом:

LoadJS предоставляет способ загрузки специфичного для страницы кода Javascript в приложении Rails без потери волшебства, предоставляемого Sprockets.Весь ваш код Javascript будет продолжен путем минимизации в одном файле Javascript, но некоторые его части будут выполняться только для определенных страниц.

https://github.com/guidomb/loadjs

3 голосов
/ 15 июля 2011

Ответ Филиппа довольно хороший.Вот код, чтобы заставить его работать:

В application.html.erb:

<body class="<%=params[:controller].parameterize%>">

Предполагая, что ваш контроллер называется Projects, он сгенерирует:

<body class="projects">

Тогда в projects.js.coffee:

jQuery ->
  if $('body.projects').length > 0  
     $('h1').click ->
       alert 'you clicked on an h1 in Projects'
2 голосов
/ 15 августа 2012

Я согласен с вашим ответом, чтобы проверить, есть ли этот селектор, используйте:

if ($(selector).length) {
    // Put the function that does not need to be executed every page
}

(никто не видел, чтобы добавить фактическое решение)

2 голосов
/ 29 мая 2011

Вот как я решил проблему стайлинга: (простите за Хамла)

%div{:id => "#{params[:controller].parameterize} #{params[:view]}"}
    = yield

Таким образом, я запускаю все специфичные для страницы .css.sass файлы с:

#post
  /* Controller specific code here */
  &#index
    /* View specific code here */
  &#new
  &#edit
  &#show

Таким образом, вы можете легко избежать любых столкновений. Когда дело доходит до файлов .js.coffee , вы можете просто инициализировать такие элементы, как;

$('#post > #edit') ->
  $('form > h1').css('float', 'right')

Надеюсь, это помогло некоторым.

2 голосов
/ 15 августа 2012

Вы также можете сгруппировать js в папки и продолжать использовать конвейер ресурсов для выборочной загрузки вашего javascript в зависимости от страницы.

2 голосов
/ 29 мая 2011

JavaScripts объединяются, только когда вы указываете Rails (скорее Sprockets) объединить их.

2 голосов
/ 28 июля 2014

Я не вижу ответа, который действительно собирает все это и выкладывает это для вас. Таким образом, я постараюсь поставить meleyal , sujal (а-ля ClosureCowboy ), первую часть ответа Райана и даже Галь смелое утверждение Гал о Backbone.js ... все вместе кратко и ясно. И, кто знает, я мог бы даже удовлетворить требования Марнена Лайбоу-Козера .

Пример редактирования

активы / JavaScripts / application.js

//= require jquery
//= require jquery_ujs
//= require lodash.underscore.min
...


просмотров / макеты / application.html.erb

  ...
  </footer>

  <!-- Javascripts ================================================== -->
  <!-- Placed at the end of the document so the pages load faster -->
  <%= javascript_include_tag "application" %>
  <%= yield :javascript %>

</body>
</html>


просмотров / Foo / index.html.erb

...
<% content_for :javascript do %>
  <%= javascript_include_tag params[:controller] %>
<% end %>


активы / JavaScripts / foo.js

//= require moment
//= require_tree ./foostuff


активы / JavaScripts / foostuff / foothis.js.coffee

alert "Hello world!"


Краткое описание

  • Удалите //= require_tree . из application.js и укажите только JS, который разделяет каждая страница.

  • Две строки, показанные выше в application.html.erb , сообщают странице, куда следует включить application.js и ваш JS для конкретной страницы.

  • Три строки, показанные выше в index.html.erb , говорят вашему взгляду искать какой-то специфичный для страницы JS и включать его в именованную область выхода, называемую ": javascript" (или как угодно Вы хотите назвать это). В этом примере контроллером является «foo», поэтому Rails попытается включить «foo.js» в область выхода: javascript в макете приложения.

  • Перечислите свой JS для конкретной страницы в foo.js (или как бы не назывался контроллер). Список общих библиотек, дерево, каталоги, что угодно.

  • Держите свой пользовательский JS для конкретной страницы там, где вы можете легко ссылаться на него отдельно от своего другого пользовательского JS. В этом примере для foo.js требуется дерево foostuff, поэтому поместите туда свой пользовательский JS, например foothis.js.coffee .

  • Здесь нет жестких правил. Не стесняйтесь перемещать вещи и, возможно, даже создавать несколько областей доходности с различными именами в различных макетах, если это необходимо. Это только показывает один возможный первый шаг вперед. (Я делаю это не совсем так, учитывая наше использование Backbone.js. Я мог бы также поместить foo.js в папку с именем foo вместо foostuff, но пока не решил этого.)

Примечания

Вы можете делать аналогичные вещи с помощью CSS и <%= stylesheet_link_tag params[:controller] %>, но это выходит за рамки вопроса.

Если я пропустил яркую лучшую практику здесь, отправьте мне записку, и я придумаю адаптацию. Rails довольно нов для меня, и, честно говоря, я до сих пор не впечатлен тем хаосом, который он по умолчанию вносит в развитие предприятия, и всем трафиком, который генерирует средняя программа Rails.

1 голос
/ 14 марта 2016

Шаг1. удалить require_tree. в вашем application.js и application.css.

Шаг2. Отредактируйте файл application.html.erb (по умолчанию на rails) в папке макета. Добавьте «params [: controller]» в следующие теги.

<%= stylesheet_link_tag    'application', params[:controller], media: 'all', 'data-turbolinks-track' => true %>

<%= javascript_include_tag 'application', params[:controller], 'data-turbolinks-track' => true %>

Step3. Добавьте файл в config / initializers / assets.rb

%w( controller_one controller_two controller_three ).each do |controller|
  Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.js.coffee", "#{controller}.css", "#{controller}.scss"]
end

ссылка: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/

1 голос
/ 26 марта 2015

Проект Paloma предлагает интересный подход к управлению javascript-кодом для конкретной страницы.

Пример использования из своих документов:

var UsersController = Paloma.controller('Users');

// Executes when Rails User#new is executed.
UsersController.prototype.new = function(){
   alert('Hello Sexy User!' );
};
1 голос
/ 31 января 2015

Хотя у вас есть несколько ответов здесь, я думаю, что ваша правка, вероятно, лучшая ставка. Шаблон проектирования, который мы используем в нашей команде, который мы получили от Gitlab , - это шаблон Dispatcher. Он делает нечто похожее на то, о чем вы говорите, однако имя страницы задается в теге body с помощью rails Например, в файле макета просто включите что-то вроде (в HAML):

%body{'data-page' => "#{controller}:#{action}" }

Тогда в вашем файле dispatcher.js.coffee в папке javascripts есть только одно замыкание и оператор switch, например:

$ ->
  new Dispatcher()

class Dispatcher
  constructor: ->
    page = $('body').attr('data-page')
    switch page
      when 'products:index'
        new Products() 
      when 'users:login'
        new Login()

Все, что вам нужно сделать в отдельных файлах (например, products.js.coffee или login.js.coffee), это заключить их в класс и затем глобализировать этот символ класса, чтобы вы могли получить к нему доступ в диспетчере:

class Products
  constructor: ->
    #do stuff
@Products = Products

У Gitlab есть несколько примеров этого, с которыми вы можете поэкспериментировать, если вам интересно:)

...