Is there a way to use a Ruby loop inside of HAML's :javascript region?

谁说胖子不能爱 提交于 2019-11-28 11:58:52

this one works

%script
  - 10.upto(20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';
%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

Running the above code gives this output:

<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>

As you can see, the big #{...} block (which may span multiple lines) runs arbitrary Ruby code. The result of the last expression (in this case the map{...}.join) is converted to a string and placed in the output.

Edit for Radek: If you want to declare a variable inside you Haml template, inside your JavaScript filter (which seems like an odd desire), then you need to be sure that the result of the block to_s doesn't produce unwanted output:

This Haml...

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

...produces this HTML:

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

Whereas this Haml...

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

...produces this HTML...

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

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

But before you do this, ask yourself: why am I creating complex Ruby variables in my view?
Shouldn't this variable have been declared by my controller?

Just wanted to add that the following gets you the type and CDATA, but without the funky behaviour of :javascript (I just had to implement something like this).

%script{ :type => 'text/javascript' }
  \//<![CDATA[
  - (10..20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';
  \//]]>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!