2015-05-08 45 views
8

我試圖在特定頁面上運行javascript,而我唯一的解決方案似乎是反模式。我在assets/javascripts/裏生成controller.js。我使用gem 'jquery-turbolinks'我有類似的代碼如下:正確的「Rails」方式在特定頁面上執行javascript

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

此代碼是在每一頁上發射所以我加入這裏面以下。

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

我的問題的存在,有沒有一種方法來設置護欄利用只需要一個特定的控制器JavaScript文件或元素背後的邏輯門尋找最佳的解決方案?

+0

我試過向application.html.erb添加<%= javascript_include_tag params [:controller]%>並刪除// = 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>

你應該注意我如果你正在使用Turbolinks,你將有一個持續運行的長時間運行的會話並保持狀態。這意味着如果您添加內聯腳本標記或在您的視圖中加載額外的JavaScript文件,它們將留在瀏覽器內存中。

因此,您可能希望清除您在page:before-unload上創建的任何頁面特定事件處理程序。

+0

非常優雅的未被發現的Turbolinks珠寶! – user3670743

+0

我已經發布了基於這種模式的寶石。 https://github.com/maxcal/pagescript – max

1

還有很多方法來做到這一點。我會描述一個。

我使用this old gem來將所有.module.js文件封裝在commonjs模塊中。

然後,我有一個幫手,在每個HTML頁面的頭部都有一個像下面這樣的標籤,寫入<script>標籤。

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

} 
+0

感謝您的解決方案。我發現這個類似的問題http://stackoverflow.com/questions/3437585/best-way-to-add-page-specific-javascript-in-a-rails-3-app?rq=1它並沒有被在那裏解決。 – maleki

相關問題