改进视图文件中的JavaScript代码

时间:2011-07-06 22:15:45

标签: javascript jquery ruby-on-rails ruby ruby-on-rails-3

我正在使用Ruby on Rails 3.0.7,我想知道如何重构 DRY (不要重复自己)和改进我的视图文件中的以下代码:

<% articles.each do |article| %>

  <div>
    <%= link_to 'add', '#', :id => "create_#{article.id}" %>
  </div>

  <script type="text/javascript">
    # Code - Block 1
    $jQ('#create_<%= article.id %>').live('click', function(event) {
      $jQ.ajax({
        type:    "POST",
        url:     "<%= article_url(@article) %>/create",
        data:    "article_id=<%= @article.id %>",
        error:   function(jqXHR, textStatus, errorThrown) {
          alert(textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
        },
        success: function(data, textStatus, jqXHR) {
          $jQ('#create_<%= article.id %>').replaceWith('<%= escape_javascript("added") + (link_to 'remove', '#', :id => "destroy_#{article.id}") %>')
        }
      });
    });

    # Code - Block 2
    $jQ('#destroy_<%= .id %>').live('click', function(event) {
      $jQ.ajax({
        type:    "POST",
        url:     "<%= article_url(@article) %>/destroy",
        data:    "article_id=<%= @article.id %>,
        error:   function(jqXHR, textStatus, errorThrown) {
          alert(textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
        },
        success: function(data, textStatus, jqXHR) {
          $jQ('#destroy_<%= article.id %>').replaceWith('<%= escape_javascript("removed") + (link_to 'add', '#', :id => "create_#{article.id}") %>')
        }
      });
    });
  </script>

<% end %>

注意

  • each声明!
  • 上面的“两个代码块”几乎相同。

2 个答案:

答案 0 :(得分:1)

  • 将主体放入字符串
  • 有两个迭代的数组(一个使用['create','added','remove',destroy'],另一个使用['destroy','removed','add','create']
  • 循环两次(0..1),为找到文本的那些插槽插入数组值
    • First Pass:array[0][0], array[0][0], array[0][0], array[0][1], array[0][2], array[0][3]
    • 第二次通过:array[1][0], array[1][0], array[1][0], array[1][1], array[1][2], array[1][3]

注意:我的Ruby生锈了,所以这里是伪代码。
示例(查找ary[i][n]):

ary = [['create','added','remove',destroy'],
       ['destroy','removed','add','create']]

for i in (0..1)
   $jQ('#**ary[i][0]_<%= article.id %>').live('click', function(event) {
      $jQ.ajax({
         type:    "POST",
         url:     "<%= article_url(@article) %>/ary[i][0]",
         data:    "article_id=<%= @article.id %>",
         error:   function(jqXHR, textStatus, errorThrown) {
                     alert(textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
                  },
         success: function(data, textStatus, jqXHR) {
                     $jQ('#ary[i][0]_<%= article.id %>')
                        .replaceWith('<%= escape_javascript("ary[i][1]") + (link_to 'ary[i][2]', '#', :id => "ary[i][3]_#{article.id}") %>')
                  }
      });
   });
end

答案 1 :(得分:0)

你可以做的是在你的文章循环中嵌套另一个方法数组,并使用它来相应地调整每个方法的内部代码块。

以下是一个例子:(未经测试但应该关闭)

<% articles.each do |article| %>

  <div>
    <%= link_to 'add', '#', :id => "create_#{article.id}" %>
  </div>

  <script type="text/javascript">
    <% [:create,:destroy].each do |method| %>
          $jQ('#<%="#{method}_#{article.id}" %>').live('click', function(event) {
            $jQ.ajax({.   
              type:    "POST",
              url:     "<%= "#{article_url(@article)}/#{method}" %>",
              data:    "article_id=<%= @article.id %>",
              error:   function(jqXHR, textStatus, errorThrown) {
                alert(textStatus + ' - ' + errorThrown + '\n\n' + jqXHR.responseText);
              },
              success: function(data, textStatus, jqXHR) {
                $jQ('#<%="#{method}_#{article.id}" %>').replaceWith('<%= escape_javascript({'create'=>'added','destroy'=>'removed'}[method]) + (link_to( {'create'=>'add','destroy'=>'remove'}[method], '#', :id => "#{method}_#{article.id}")) %>')
              }
            });
          });

    <% end %>
  </script>
<% end %>

你的其他选择是把它变成一个辅助方法,它接受一篇文章和一个方法并生成正确的输出,或者你可以将必要的数据放在html标签中并让javascript转换它。