16

在 HAML 内部,我们可以在 :javascript 区域内有一个循环吗?

这将起作用:

- 10.upto(20) do |i|
  :javascript
    document.getElementById('aDiv').innerHTML += '#{i}';

这不会:

:javascript
  - 10.upto(20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';

上面的代码也可以工作吗?

4

3 回答 3

13
%html
  %head
    :javascript
      var foo = [];
      #{
        limit = rand(4)+3
        array = (0..limit).to_a
        array.map{ |i| "foo[#{i}] = #{rand(12)};" }.join ' '
      }
      console.log(foo.length);
    %body

运行上面的代码给出这个输出:

<html>
  <head>
    <script type='text/javascript'>
      //<![CDATA[
        var foo = [];
        foo[0] = 2; foo[1] = 0; foo[2] = 11; foo[3] = 8; foo[4] = 0; foo[5] = 1;
      //]]>
    </script>
    <body></body>
  </head>
</html>

如您所见,#{...}大块(可能跨越多行)运行任意 Ruby 代码。最后一个表达式的结果(在本例中为map{...}.join)被转换为字符串并放置在输出中。

为 Radek 编辑:如果你想在 Haml 模板中声明一个变量,在你的 JavaScript 过滤器中(这似乎是一个奇怪的愿望),那么你需要确保块的结果to_s不会产生不需要的输出:

这个哈姆...

%p
  :javascript
    var foo = 12;
    #{x = 42}
    var bar = #{x};

...产生这个 HTML:

<p>
  <script type='text/javascript'>
    //<![CDATA[
      var foo = 12;
      42
      var bar = 42;
    //]]>
  </script>
</p>

而这个哈姆...

%p
  :javascript
    var foo = 12;
    #{x = 42; ""}
    var bar = #{x};

...生成此 HTML ...

<p>
  <script type='text/javascript'>
    //<![CDATA[
      var foo = 12;

      var bar = 42;
    //]]>
  </script>
</p>

但在你这样做之前,问问自己:为什么我要在我的视图中创建复杂的 Ruby 变量?
我的控制器不应该声明这个变量吗?

于 2011-05-03T03:10:51.490 回答
13

这个有效

%script
  - 10.upto(20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';
于 2010-06-02T23:19:02.137 回答
4

只是想补充一点,以下内容可以为您提供类型和 CDATA,但没有 :javascript 的时髦行为(我只需要实现类似这样的东西)。

%script{ :type => 'text/javascript' }
  \//<![CDATA[
  - (10..20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';
  \//]]>
于 2011-04-05T18:34:30.647 回答