Правильный "Rails" способ выполнения JavaScript на определенных страницах
Я пытаюсь запустить javascript на определенных страницах, и мое единственное решение похоже на анти-шаблон. я имею controller.js
генерируется внутри assets/javascripts/
, я использую gem 'jquery-turbolinks'
У меня есть код, похожий на следующий:
$(document).ready(function () {
//Initiate DataTables ect..
}
)
Этот код срабатывает на каждой странице, поэтому я добавил в него следующее.
if ($('#page-specific_element').length > 0) {
//Initiate Datatables ect.
}
Мой вопрос заключается в том, есть ли способ настроить рельсы для использования только файлов javascript, необходимых для конкретного контроллера, или логическое управление за поиском элементов является лучшим решением?
2 ответа
Это довольно приятное решение:
<body data-controller="<%= controller.controller_name %>" data-action="<%= controller.action_name %>">
// Instead of listening for document ready
$(document).on('users#show:loaded', function(){
$('#logger').append('<li>Users Show action loaded</li>');
});
// Instead of listening for document ready
$(document).on('users:loaded', function(){
$('#logger').append('<li>Some users controller method loaded</li>');
});
// Turbolinks fires "page:change" when it changes the page content.
// you could change this to just document ready if you are not using
// turbolinks.
$(document).on("page:change", function(){
var data = $('body').data();
$(document).trigger(data.controller + ':loaded');
$(document).trigger(data.controller + '#' + data.action + ':loaded');
});
// This is just for demonstration purposes...
$(document).trigger("page:change");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body data-controller="users" data-action="show">
<ul id="logger"></ul>
</body>
Следует отметить, что если вы используете Turbolinks, у вас будет длительный, постоянный сеанс с сохраненным состоянием. Это означает, что если вы добавите теги встроенного скрипта или загрузите дополнительные файлы JavaScript в свои представления, они будут задерживаться в памяти браузера.
Поэтому вы, возможно, захотите очистить любые обработчики событий для конкретной страницы, которые вы создали на page:before-unload
,
Есть много способов сделать это. Я опишу один.
Я использую этот старый драгоценный камень, чтобы обернуть все мои .module.js
файлы в модулях commonjs.
Затем у меня есть помощник, который пишет что-то вроде следующего <script>
тег в заголовке каждой HTML-страницы.
<script>
var App {
pageModule: 'posts/create'
};
</script>
posts/create
генерируется из упрощенного сочетания текущего контроллера и действия, выполняющего запрос.
Затем у меня есть что-то вроде следующего в моем domready для моего application.js
,
try { App.pageModule = require(App.pageModule); } catch(e) { console.log('%c' + e, 'color:red; background-color:yellow'); }
if (_.isPlainObject(App.pageModule) && _.has(App.pageModule, 'initialize')) {
App.pageModule.initialize();
}
Наконец, у меня будет такой файл, который относится к /posts/create
URL.
приложение / активы / сообщения /create.module.js
module.exports = {
initialize: function() {
// data-tables stuff here...
}
}