Есть ли способ использовать цикл Ruby внутри области HAML: javascript? - PullRequest
14 голосов
/ 03 июня 2010

Внутри HAML, можем ли мы иметь цикл внутри области: javascript?

Это будет работать:

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

и это не будет:

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

Можно ли сделать так, чтобы вышеприведенный код тоже работал?

Ответы [ 3 ]

13 голосов
/ 03 мая 2011
%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 в моем представлении?
Разве эта переменная не была объявлена ​​моим контроллером?

11 голосов
/ 03 июня 2010

это работает

%script
  - 10.upto(20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';
4 голосов
/ 05 апреля 2011

Просто хотел добавить, что следующий код дает вам тип и CDATA, но без прикольного поведения: javascript (мне просто нужно было реализовать что-то подобное).

%script{ :type => 'text/javascript' }
  \//<![CDATA[
  - (10..20) do |i|
    document.getElementById('aDiv').innerHTML += '#{i}';
  \//]]>
...