2012-08-28 32 views
1

我有標準的rails應用程序格式。加載一個JavaScript,並運行它在一個特定的控制器和在rails中的具體操作

我有這些控制器:

class StaticPagesController < ApplicationController 

    def help 
    end 

    def about 
    end 

end 

和我有文件app/assets/javascripts/static_page.js.coffee

我想兩兩件事:

  1. 加載以下JavaScript ONLY當我運行其中一頁是static_pages

  2. 能夠使取決於控制器內的具體行動不同的js調用:

的JavaScript文件應該是這樣的:

//general javascript code 
if (isThisHelpPage) { 
    //Run some help page code 
} 

if (isThisAboutPage) { 
    //Run some about page code 
} 

我認爲第一個問題應該得到解決以某種方式與app/assets/javascripts/application.js文件通過添加一些規則,如:

//= require jquery 
//= require jquery_ujs 
//= require bootstrap 
//= require_tree . 

//= (isItStaticController? render static_page.js.coffee) 

但我想知道我該怎麼做?

回答

1

不幸的是,您不能將條件添加到應用程序js文件中,因爲它在部署應用程序時被預編譯。 有,我可以看到在這裏爲你工作的兩個潛在的方法:

1)將所有的JavaScript在一個單一的文件,你有上面再設置頁面在你的代碼是這樣的:

<script> page = "Help" </script> or <script> page = "About" </script> 

你的腳本然後可以成爲:

if(page === "Help") .... else if(page === "About") .... 

2)另一種選擇是創建單獨的js文件的每一頁,然後通過產量納入他們:在你的佈局頭塊。在您的幫助文件,它應該是這樣的:

<% content_for :head %> 
    <%= javascript_include_tag 'help' %> 
<% end %> 

我個人贊成我的應用程序的第二種方法。

+0

如果你選擇2,不要忘記在你的'application.js'中相應的改變'// = require_tree .'行,否則你的控制器特定的文件最終會在每個頁面上加載。 – Felix

+0

謝謝菲利克斯,忘了提及。 – apchester

0

我會解釋我是如何處理這個的。在我的ApplicationController中,我有一個從每個請求上的before_filter運行的方法。

def prepare_common_variables 
    controller_name = self.class.name.gsub(/Controller$/, '') 
    if !controller_name.index('::').nil? 
    namespace, controller_name = controller_name.split('::') 
    end 

    @default_body_classes = ["#{controller_name.underscore}_#{action_name} ".downcase.strip] 
    @default_body_classes = ["#{namespace.underscore}_#{@default_body_classes.join}".strip] if !namespace.nil? 
end 

app/views/layouts/application.html.erb我有以下

<body class="<%= yield :body_classes %> <%= @default_body_classes.join(' ') %>"> 

爲了您StaticPagesController,則help動作運行時,這將產生以下<body>標籤:

​​

接下來,我有一個像我這樣的方法app/assets/javascripts/application.js.erb

Array.prototype.diff = function(a) { 
    return this.filter(function(i) {return !(a.indexOf(i) > -1);}); 
}; 

var DEEFOUR = (function (deefour) { 
    deefour.Utility = (function (utility) { 
    utility.hasBodyClass = function() { 
     var args = Array.prototype.slice.call(arguments); 
     if (args.length === 0 || $('body').get(0).attr('class') == "") return false; 

     return args.diff($('body').get(0).attr('class').split(/\s/)).length == 0; 
    }; 

    return utility; 
    }(deefour.Utility || {})); 

    return deefour; 
}(DEEFOUR || {})); 

最後,我相當於你app/assets/javascripts/static_page.js.coffee的我都會有這樣的事情

$(function(){ 
    if (!DEEFOUR.Utility.hasBodyClass('static_pages_help')) return; 

    // code for your help page 
}); 

$(function(){ 
    if (!DEEFOUR.Utility.hasBodyClass('static_pages_about')) return; 

    // code for your about page 
}); 

這是不錯的,因爲在你看來

<% content_for :body_classes, :some_custom_class %> 

或特定行動中

@default_body_classes << "some_other_custom_class" 

你可以有條件地添加特定的類來匹配你的Java腳本。

// *both* 'static_pages_help' and 'some_other_class' are required 
if (!DEEFOUR.Utility.hasBodyClass('static_pages_help') || !DEEFOUR.Utility.hasBodyClass('some_other_class')) return; 

hasBodyClass(...)接受的參數的任意#;只是列出來。這對於像newcreate這樣的操作非常有用,您希望在表單未能提交時運行相同的Javascript。

if (!DEEFOUR.Utility.hasBodyClass('some_controller_new', 'some_controller_create')) return; 

應該指出,prepare_common_variables需要一些調整,因爲它僅允許像SomeNamespace::TheController一個單一命名空間,而不是更像SomeNamespace::AnotherNamespace::TheController

0

這裏最好的做法是使用content_for helper方法。有點像通過@Adam描述,但你可能想提出一個<%= yield :script_files %>在佈局文件的底部,然後從你希望它是在動作中調用

<% content_for :script_files do %> 
    <%= javascript_include_tag 'your_js_file' %> 
<% end %> 

。你甚至可以通過清潔劑如由Ryan貝茨在Railscast早期提到以下類似的方法做到這一點:

module ApplicationHelper 
    def javascripts(paths) 
    content_for :script_files do 
     javascript_include_tag(paths.is_a?(Array) ? paths.join(',') : paths) 
    end 
    end 
end 

然後,可以從你的行動來看,只是叫<% javascripts 'your_js_file' %>,並有包括該文件。

0

加載以下JavaScript只有當我運行的static_pages

首先所有的頁面之一,資產管道編譯並創建靜態資產文件offline,這意味着你不能創建動態的基於包在服務用戶請求期間(在生產中)在控制器名稱上。

但是,您可以在相應的佈局文件(StaticPages控制器)中使用單獨的<%= javascript_include_tag "static_page_manifest.js" %>聲明代替(包括application.js)來爲特定視圖定義特定的javascript。例如,你可以有一個app/assets/javascripts/static_page_manifest.js

//= require jquery 
//= require jquery_ujs 
//= require bootstrap 
//= require_tree . 

//= static_page 

另外,如果你想動態JavaScript模塊包容,你可以使用requirejsrequirejs-rails)等

能夠使取決於不同的js調用控制器內部的具體動作

這可以通過檢查一個主體標記id取決於控制器和動作名稱的值來實現!例如:

<body id="static_pages_<%= controller.action_name %>"> 
... 

然後你可以在javascript包中檢查這個id值來執行某些代碼片段。

相關問題