Правильный "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...
  }

}
Другие вопросы по тегам