这里的问题是您不能在过滤器中使用普通的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 对象上的一个方法,它返回一个用于打印的名称),或者可能更改辅助方法以提取您要使用的字符串。