Насколько я понимаю, все ваши 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
es. В коде JavaScript вы просто проверяете, присутствует ли id
или class
на странице, и, если это так, вы запускаете связанный с ним код JavaScript. Таким образом, если динамический элемент отсутствует на странице, код JavaScript не запускается, даже если он включен в большой application.js
файл, упакованный Sprockets.
Мое вышеупомянутое решение имеет то преимущество, что если окно поиска включено на 8 из 100 страниц, оно будет работать только на этих 8 страницах. Вам также не придется включать этот код на 8 страницах сайта. На самом деле, вам больше никогда не придется добавлять теги сценариев вручную на ваш сайт.
Я думаю, что это фактический ответ на мой вопрос.
источник
application.js
), и фактически указанная вами ссылка указывает, почему это так: загрузка - это самая медленная часть процесса выполнения JS. Многие маленькие файлы более кешируются, чем один большой. Таким образом, люди Unholy Rails, похоже, не осознают, что их рекомендации не соответствуют принципам, которых они пытаются придерживаться, и поэтому к их рекомендациям не следует относиться серьезно.Ответы:
Документы Asset Pipeline предлагают, как сделать JS для конкретного контроллера:
Ссылка на: asset_pipeline
источник
page_specific_js = "#{params[:controller]}_#{params[:action]}"
а потом;javascript_include_tag page_specific_js if Rails.application.assets.find_asset page_specific_js
Для js для конкретной страницы вы можете использовать решение Garber-Irish .
Таким образом, ваша папка Rails javascripts может выглядеть так для двух контроллеров - автомобилей и пользователей:
И javascripts будет выглядеть так:
и markup_based_js_execution будет содержать код для объекта UTIL, а также для выполнения UTIL.init, готового к DOM.
И не забудьте поместить это в свой файл макета:
Я также думаю, что лучше использовать классы вместо
data-*
атрибутов, для лучшего CSS для конкретной страницы. Как упоминал Джейсон Гарбер: CSS-селекторы для конкретной страницы могут быть очень неудобными (когда вы используетеdata-*
атрибуты)Я надеюсь, что это поможет вам.
источник
window.varForOneController='val'
этой функции инициализации контроллера. Также здесь может помочь Gon Gem ( github.com/gazay/gon ). Могут быть и другие обходные пути.//= require_tree .
и использовать специфичный для страницы JavaScript. Если вы активно пытаетесь не делать этого, тогда вы стремитесь к плохой практике.Я вижу, что вы ответили на свой вопрос, но вот еще один вариант:
По сути, вы делаете предположение, что
необходимо. Это не. Не стесняйтесь удалить это. В моем текущем приложении, честно говоря, первое, что я делаю с 3.1.x, я сделал три разных JS-файла верхнего уровня. мой
application.js
файл имеет толькоТаким образом, я могу создавать подкаталоги с собственными JS-файлами верхнего уровня, которые содержат только то, что мне нужно.
Ключи:
require_tree
- Rails позволяет вам изменить предположения, которые он делаетapplication.js
- любой файл вassets/javascript
подкаталоге может содержать директивы препроцессора с//=
Надеюсь, что это помогает и добавляет некоторые детали к ответу ClosureCowboy.
Sujal
источник
//= require_tree .
на//= require_directory .
так, чтобы вы могли хранить все существующие файлы там, где они есть, и создавать новые каталоги для файлов, специфичных для страницы.Другой вариант: для создания файлов, специфичных для страницы или модели, вы можете создавать каталоги внутри своей
assets/javascripts/
папки.Ваш основной
application.js
файл манифеста может быть настроен для загрузки его файлов изglobal/
. Определенные страницы или группы страниц могут иметь свои собственные манифесты, которые загружают файлы из их собственных определенных каталогов. Звездочки автоматически объединят загруженные файлыapplication.js
с файлами, специфичными для вашей страницы, что позволяет этому решению работать.Эту технику можно использовать и для
style_sheets/
.источник
Я ценю все ответы ... и я не думаю, что они действительно решают проблему. Некоторые из них касаются стиля и, кажется, не связаны ... а другие просто упоминают
javascript_include_tag
... что я знаю, что существует (очевидно ...), но может показаться, что путь к Rails 3.1 - это завершение всего Ваш Javascript в 1 файл, а не загружать отдельный Javascript внизу каждой страницы.Лучшее решение, которое я могу придумать, - это обернуть некоторые функции в
div
тегиid
s илиclass
es. В коде JavaScript. Тогда вы просто проверить , еслиid
илиclass
на странице, и если вы запустите код яваскрипта, связанный с ним. Таким образом, если динамический элемент отсутствует на странице, код javascript не запускается, даже если он включен в огромныйapplication.js
файл, упакованный Sprockets.Мое вышеупомянутое решение имеет то преимущество, что если окно поиска включено на 8 из 100 страниц, оно будет работать только на этих 8 страницах. Вам также не придется включать этот код на 8 страницах сайта. На самом деле, вам больше никогда не придется включать теги сценариев вручную на ваш сайт, кроме как для предварительной загрузки данных.
Я думаю, что это фактический ответ на мой вопрос.
источник
<script>
теги. Да, классы и идентификаторы являются частью ответа, но для пользователя нет смысла загружать JavaScript, который не требуется для этой конкретной страницы.Я понимаю, что прихожу на эту вечеринку немного поздно, но я хотел добавить решение, которое я использовал в последнее время. Тем не менее, позвольте мне сначала упомянуть ...
Rails 3.1 / 3.2 Way (Нет, сэр. Мне это не нравится.)
Смотрите: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Для полноты изложения я включаю следующее и потому, что это не является нежизнеспособным решением ... хотя меня это не волнует.
«Rails Way» - это решение, ориентированное на контроллеры, а не ориентированное на просмотр, как просил первоначальный автор этого вопроса. Существуют специфичные для контроллера файлы JS, названные в честь соответствующих контроллеров. Все эти файлы помещаются в дерево папок, которое по умолчанию НЕ включено ни в одно из приложений. Js требуют директив.
Чтобы включить специфичный для контроллера код, в представление добавляется следующее.
Я ненавижу это решение, но оно есть и оно быстрое. Предположительно, вместо этого вы можете называть эти файлы чем-то вроде «people-index.js» и «people-show.js», а затем использовать что-то подобное,
"#{params[:controller]}-index"
чтобы получить ориентированное на представление решение. Опять же, быстрое решение, но мне это не подходит.Мой путь к данным
Считай меня сумасшедшим, но я хочу, чтобы ВСЕ мои JS компилировались и минимизировались в application.js при развертывании. Я не хочу помнить, чтобы включить эти маленькие файлы бродяги повсюду.
Я загружаю все свои JS в один компактный файл, который скоро будет кэширован браузером. Если какой-то кусок моего application.js нужно запустить на странице, я позволяю HTML сказать мне, а не Rails.
Вместо того, чтобы привязывать мой JS к определенным идентификаторам элементов или засорять мой HTML классами маркеров, я использую пользовательский атрибут данных с именем
data-jstags
.На каждой странице я использую - вставьте предпочтительный метод библиотеки JS здесь - для запуска кода после завершения загрузки DOM. Этот код начальной загрузки выполняет следующие действия:
data-jstag
Скажем, у меня в файле application.js определено следующее:
Событие начальной загрузки будет применять функции
my_autosuggest_init
иmy_hint_init
к вводу поиска, превращая его во ввод, который отображает список предложений при вводе пользователем, а также предоставляет некоторую подсказку для ввода, когда ввод оставлен пустым и не сфокусированным.Если какой-либо элемент не помечен
data-jstag="auto-suggest"
, код автоматического предложения никогда не срабатывает. Тем не менее, он всегда присутствует, минимизируется и в конечном итоге кэшируется в моем application.js для тех случаев, когда он мне нужен на странице.Если вам нужно передать дополнительные параметры вашим тегированным функциям JS, вам придется применить некоторые творческие возможности. Либо добавьте атрибуты data-paramter, придумайте некоторый синтаксис параметров или даже используйте гибридный подход.
Даже если у меня есть какой-то сложный рабочий процесс, который кажется специфичным для контроллера, я просто создам файл для него в своей папке lib, запакую его в application.js и добавлю к нему что-то вроде 'new-thing-wizard'. Когда мой загрузчик попадет в этот тег, будет создан и запущен мой милый, причудливый волшебник. Он работает для представлений этого контроллера, когда это необходимо, но никак не связан с контроллером. Фактически, если я правильно закодирую свой мастер, я смогу предоставить все данные конфигурации в представлениях и, следовательно, позже смогу повторно использовать мой мастер для любого другого контроллера, который нуждается в этом.
Как бы то ни было, именно так я уже давно внедряю JS для конкретных страниц, и это хорошо мне помогло как для простого дизайна сайта, так и для более сложных / насыщенных приложений. Надеемся, что одно из двух решений, которые я представил здесь, мой путь или путь Rails, будет полезно всем, кто сталкивается с этим вопросом в будущем.
источник
На это уже давно был дан ответ, но я придумал собственное решение, основанное на некоторых из этих ответов и моем опыте работы с Rails 3+.
Трубопровод активов сладок. Используй это.
Сначала в вашем
application.js
файле удалите//= require_tree.
Затем
application_controller.rb
создайте вспомогательный метод:Затем в
application.html.erb
файле макета добавьте нового помощника среди существующих включений javascript с префиксомraw
помощника:Вуаля, теперь вы можете легко создавать javascript для конкретного вида, используя ту же файловую структуру, что и везде в rails. Просто вставьте свои файлы
app/assets/:namespace/:controller/action.js.erb
!Надеюсь, что это помогает кому-то еще!
источник
<%= raw ... %>
вернет 404?require_tree /
(плохим)?Вы можете добавить эту строку в свой файл макета (например, application.html.erb), чтобы автоматически загрузить специфичный для контроллера файл javascript (тот, который был создан при создании контроллера):
Вы также можете добавить строку для автоматической загрузки файла сценария для каждого действия.
Просто поместите скрипты вашей страницы в подкаталог с именем контроллера. В эти файлы вы можете включить другие скрипты, используя = require. Было бы неплохо создать помощника для включения файла, только если он существует, чтобы избежать сбоя 404 в браузере.
источник
источник
Может быть, вы найдете гем pluggable_js как подходящее решение.
источник
LoadJS камень другой вариант:
источник
Ответ Филиппа довольно хороший. Вот код, чтобы заставить это работать:
В application.html.erb:
<body class="<%=params[:controller].parameterize%>">
Предполагая, что ваш контроллер называется Projects, он сгенерирует:
<body class="projects">
Тогда в projects.js.coffee:
источник
<body>
это в силу самого факта неверно. Смотрите мои комментарии в другом месте на этой странице.JavaScripts объединяются только тогда, когда вы говорите Rails (скорее Sprockets) объединить их.
источник
//= require_tree .
?require_tree .
обычно плохая идея.Вот как я решил проблему стайлинга: (извините, Хэмл)
Таким образом, я запускаю все специфичные для страницы файлы .css.sass с:
Таким образом, вы можете легко избежать любых столкновений. Когда дело доходит до файлов .js.coffee, вы можете просто инициализировать такие элементы, как;
Надеюсь, это помогло некоторым.
источник
$('#post > #edit') ->
кажется, недействительным. Как вы используете JQuery для работы в области?= javascript_include_tag "application"
и= javascript_include_tag params[:controller]
таким образом я могу держать код JavaScript без необходимости указывать область внутри файла.Вы также можете сгруппировать js по папкам и продолжать использовать конвейер ресурсов для выборочной загрузки вашего javascript в зависимости от страницы.
источник
Я согласен с вашим ответом, чтобы проверить, есть ли этот селектор, используйте:
(никто не видел, чтобы добавить фактическое решение)
источник
Я не вижу ответа, который действительно объединяет все это и выкладывает это для вас. Таким образом, я попытаюсь поставить meleyal , sujal (а - ля ClosureCowboy ), первая часть Райана ответа, и даже Галь смелое заявление о Backbone.js ... все вместе в пути , который коротко и ясно. И, кто знает, я мог бы даже удовлетворить требования Марнена Лайбоу-Козера .
Пример редактирования
assets / javascripts / application.js
views / layouts / application.html.erb
views / foo / index.html.erb
assets / javascripts / foo.js
assets / javascripts / foostuff / foothis.js.coffee
Краткое описание
Удалите
//= 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.
источник
У меня есть другое решение, которое, хотя примитив отлично работает для меня и не нуждается в каких-либо причудливых выборочных стратегиях загрузки. Поместите в свою обычную функцию готовности документа, но затем проверьте текущее местоположение окон, чтобы увидеть, предназначена ли это страница, для которой предназначен ваш javascript:
Это по-прежнему позволяет загружать все js с помощью rails 3.x в одном небольшом пакете, но не создает больших накладных расходов или конфликтов со страницами, для которых js не предназначен.
источник
Ответ ryguy является хорошим ответом, даже несмотря на то, что его оценили как негативные.
Особенно, если вы используете что-то вроде Backbone JS - каждая страница имеет свой собственный вид Backbone. Тогда у файла erb есть единственная строка встроенного javascript, который запускает правый базовый класс представления. Я считаю, что это единственная строка «склеивающего кода» и, следовательно, тот факт, что с ней все в порядке. Преимущество заключается в том, что вы можете сохранить ваше «require_tree», которое позволяет браузеру кэшировать весь javascript.
в show.html.erb у вас будет что-то вроде:
и в вашем файле макета вам понадобится:
источник
Переместите все ваши JS-файлы commom в подпапку, например «app / assets / javascript / global», затем в application.js измените
//= require_tree .
строку на//= require_tree ./global
.Теперь вы можете поместить свой JS, специфичный для контроллера, в корень «app / assets / javascript /», и они не будут включены в скомпилированный JS, а используются только тогда, когда вы вызываете их через
= javascript_include_tag
контроллер / представление.источник
Хотя у вас есть несколько ответов здесь, я думаю, что ваша редакция, вероятно, лучшая ставка. Шаблон проектирования, который мы используем в нашей команде, который мы получили от Gitlab, - это шаблон Dispatcher. Он делает нечто похожее на то, о чем вы говорите, однако имя страницы задается в теге body с помощью rails. Например, в вашем файле макета просто включите что-то вроде (в HAML):
Тогда в вашем
dispatcher.js.coffee
файле javascripts есть только одно замыкание и инструкция switch в вашем файле:Все, что вам нужно сделать в отдельных файлах (скажем
products.js.coffee
или,login.js.coffee
например), это заключить их в класс и затем глобализировать этот символ класса, чтобы вы могли получить к нему доступ в диспетчере:У Gitlab есть несколько примеров этого, с которыми вы можете поэкспериментировать, если вам интересно :)
источник
Проект Paloma предлагает интересный подход к управлению javascript-кодом для конкретной страницы.
Пример использования из их документов:
источник
Шаг 1. удалить require_tree. в вашем application.js и application.css.
Шаг 2. Отредактируйте файл application.html.erb (по умолчанию на rails) в папке макета. Добавьте «params [: controller]» в следующие теги.
Шаг 3. Добавьте файл в config / initializers / assets.rb
ссылки: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/
источник
Я не пробовал это, но похоже, что верно следующее:
если у вас есть content_for, который является javascript (например, с реальным javascript внутри него), sprockets не будет знать об этом, и, следовательно, это будет работать так же, как и сейчас.
если вы хотите исключить файл из большого пакета javascript, вы должны зайти в файл config / sprockets.yml и соответственно изменить исходные файлы. Затем вы просто включите любые файлы, которые вы исключили, где это необходимо.
источник
Я делал это ранее, используя этот метод: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/ . Супер-легкий, полагается на контроллеры, чтобы выбрать правильный JS для загрузки.
источник
Я объединил некоторые ответы в:
Помощник по применению:
макеты / application.html.haml:
источник
Первый: удалить
\\=require_tree
из application.js. Второй: весь ваш код JS должен быть размещен в,/app/assets/javascritpt
а весь ваш код CSS - в/app/assets/stylesheets
источник
Следуя указаниям Райана, вот что я сделал:
application.js.coffee
users.js.coffee (специфический для контроллера coffeescript, например controller: users, action: dashboard)
application.html.haml
источник
eval
), если ваш HTML-код скомпрометирован взломанным сервером или вредоносным скриптом пользователя.Вот как это сделать, особенно если вам не нужно запускать тонны библиотек для конкретной страницы, а выполнять более или менее несколько сотен строк JS.
Поскольку встраивать код Javascript в HTML совершенно нормально, просто создайте его в каталоге app / views shared.js и поместите туда свой код для страниц / страниц в my_cool_partial.html.erb.
Так что теперь, откуда вы хотите, вы просто делаете:
И это все, к?
источник