2011-05-12 93 views
3

我在基於Sinatra的Web應用程序中使用Haml作爲我的模板語言,並且在基於來自數據庫模型的信息生成JavaScript數組時遇到問題。基本上,我試圖生成一個由用戶名組成的JavaScript數組,用於jQuery-UI自動完成小部件。在Sinatra幫助程序中生成JavaScript

我試過下面的代碼,但它沒有工作。取而代之的是,大多數人在閱讀完之後,建議在輔助工具中做任何涉及評估Ruby的任何事情(即任何在Haml中以' - '開頭的詞)。所以,鑑於此,任何人都可以向我解釋如何在輔助方法中生成JavaScript?

回答

4

這裏的問題是,你不能在過濾器中正常使用HAML功能(例如:javascript)。然而,過濾器中的文本會受到正常的ruby字符串插值的影響,即#{}內的任何內容都將作爲Ruby代碼執行。

所以讓你的例子來工作的一個方法是這樣的:

:javascript 
    var names = new Array; 
    #{js = "" 
    User.all.each {|u| js << "names.push(#{u})\n" } 
    js} 

這是相當混亂,雖然,整理一下的方法是將其移動到一個幫手。助手只是一個在渲染期間處於範圍內的方法(因此可以在haml文件中調用它),並生成一些文本以包含在生成的頁面中。

在這種情況下,您正在生成JavaScript,但JavaScript只是文本,所以這裏沒有問題。輔助方法可能是這個樣子:

def js_array(name, array) 
    js = "var #{name} = new Array();\n" 
    array.each do |i| 
    js << "#{name}.push(#{i})\n" 
    end 
    js 
end 

(或者你可以創建一個文本JavaScript數組:如果您首選

def js_array(name, array) 
    js = "var #{name} = [" 
    js << array.collect{|i| "\"#{i}\""}.join(",") 
    js << "]" 
    js 
end 

。)

接下來,就這種方法去?在Sinatra中,您使用'helpers` method定義了輔助方法。在此塊中定義的任何方法將你的意見是可用:

helpers do 
    def js_array(name, array) 
    js = "var #{name} = new Array();\n" 
    array.each do |i| 
     js << "#{name}.push(#{i})\n" 
    end 
    js 
    end 
end 

有了這個地方,那麼你可以做

:javascript 
    #{js_array("names", User.all)} 

在HAML生成您的JavaScript數組。請注意,你仍然需要#{},這樣ruby代碼纔會被執行,現在只需要在大括號之間調用一個方法。:javascript過濾器會將該塊包裝在<script><![CDATA[標籤中,並且幫助程序將創建您想要的實際JavaScript。

還有一件事:在你的例子中,數組是User.all,它看起來像是對activerecord的調用或類似的東西,在這種情況下,你可能沒有一個字符串數組,但是可能沒有給出結果的其他對象想。您可能需要做一些事情,如:

:javascript 
    #{js_array("names", User.all.collect(&:pretty_name)} 

(其中pretty_nameUser對象打印返回名字的方法),或者改變輔助方法來提取您要使用的字符串。

+0

太棒了,謝謝馬特!我將其標記爲答案,因爲它強調了如何使用助手來生成與haml一起使用的javascript。 – Bryan 2011-05-19 19:57:06

2

與其讓輔助方法生成JavaScript,您可能希望它返回可用作視圖中jQuery UI自動填充小部件源的名稱數組。

所以,你的helper方法,會是這個樣子:

helpers do 
    # Return an array of users' names 
    def get_all_names 
    return User.all.map {|u| u.name} 
    end 
end 

而在你的Haml的:

:javascript 
    $(function() { 
    var names = #{get_all_names.to_json}; 
    $("#widget").autocomplete({ source: names }); 
    }); 
+0

謝謝Kunal!這也很有用,因爲它告訴我如何在現有的javascript函數中使用助手的結果。 – Bryan 2011-05-19 19:57:46