2015-05-08 3 views
8

Я пытаюсь запустить javascript на определенных страницах, и мое единственное решение похоже на анти-шаблон. У меня есть controller.js, сгенерированный внутри assets/javascripts/. Я использую gem 'jquery-turbolinks' У меня есть код, похожий на следующее:Правильный способ «Rails» для выполнения javascript на определенных страницах

$(document).ready(function() { 
    //Initiate DataTables ect.. 
    } 
) 

Этот код стреляя на каждой странице, поэтому я добавил следующее внутри него.

if ($('#page-specific_element').length > 0) { 
    //Initiate Datatables ect. 
} 

Мой вопрос заключается в том, есть ли способ установить рельсы использовать только JavaScript файлы, необходимые для конкретного контроллера или логика стробирования за элементом поиска наилучшего решения?

+0

Я попытался добавить <% = javascript_include_tag params [: controller]%> в application.html.erb и удалить // = require_tree. из application.js в качестве части решения, но я столкнулся с необходимостью добавить каждый «controller.js» в файл компиляции активов, который, кажется, идет по неправильной дороге. – maleki

ответ

15

Это довольно хорошие turbolinks конкретное решение:

<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>

You следует отметить, что i Если вы используете Turbolinks, у вас будет длительный постоянный сеанс с сохраненным состоянием. Это означает, что если вы добавите теги встроенного скрипта или загрузите дополнительные файлы javascript в свои представления, они будут задерживаться в памяти браузеров.

Возможно, поэтому вы захотите очистить любые обработчики конкретных страниц, созданные на page:before-unload.

+0

Чрезвычайно элегантный неоткрытый драгоценный камень Turbolinks! – user3670743

+0

Я выпустил камень, основанный на этом шаблоне. https://github.com/maxcal/pagescript – max

1

Есть много способов для этого. Я опишу один.

Я использую this old gem, чтобы обернуть все мои файлы .module.js в модулях commonjs.

У меня есть помощник, который пишет что-то вроде следующего тега <script> в начале каждой HTML-страницы.

<script> 
    var App { 
    pageModule: 'posts/create' 
    }; 
</script> 

posts/create генерируется из упрощенной смеси текущего контроллера и действия, оказывающего запрос.

В моем доме уже есть что-то вроде следующего: 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... 
    } 

} 
+0

Спасибо за это решение. Я нашел этот аналогичный вопрос http://stackoverflow.com/questions/3437585/best-way-to-add-page-specific-javascript-in-a-rails-3-app?rq=1, и он не был адресованный там. – maleki

Смежные вопросы