我在基于Sinatra的Web应用程序中使用Haml作为我的模板语言,而且我在根据数据库模型的信息生成JavaScript数组时遇到了麻烦。基本上,我正在尝试生成一个由用户名组成的JavaScript数组,以便在jQuery-UI自动完成小部件中使用。
我尝试了以下代码,但它没有用。
:javascript
var names = new Array;
- User.all.each do |u|
names.push(#{u})
在阅读之后,大多数人建议做一些涉及在帮助器中评估Ruby(即在Haml中以' - '为前缀的任何东西)的任何事情。那么,鉴于此,任何人都可以向我解释如何在辅助方法中生成JavaScript吗?
答案 0 :(得分: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_name
是User
对象上返回打印名称的方法,或者可能更改帮助方法以提取您要使用的字符串。
答案 1 :(得分:2)
您可能希望它返回名称数组,而不是让helper方法生成JavaScript,然后可以将其用作视图中jQuery UI Autocomplete小部件的源。
所以你的帮助方法看起来像这样:
helpers do
# Return an array of users' names
def get_all_names
return User.all.map {|u| u.name}
end
end
在你的汉姆尔:
:javascript
$(function() {
var names = #{get_all_names.to_json};
$("#widget").autocomplete({ source: names });
});