rails:访问js.erb中的非实例变量

时间:2011-12-03 20:05:28

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

我有一个呈现多个表单的页面。目前,当用户提交这些表单中的任何一个时,它会使用刚刚提交的表单中的内容更新(通过ajax)同一页面上的div。

我还想删除()ajax post请求完成后刚刚提交的表单元素。但是,我需要能够访问js.erb文件中的特定表单ID来执行此操作。

由于我的页面有x个动态呈现的表单,我不能简单地访问js.erb中的实例变量。

页:

<% for peer_review in @peer_reviews %>
    <%= render :partial => 'form', :locals => { :peer_review => peer_review } %>
<% end %>

<div id="completed_peer_reviews">
    <%= render 'completed_peer_reviews' %>
</div>

@pere_reviews实例变量包含一个已包含一些数据的新PeerReview对象数组。

形式:

<div id="peer_review_form_<%= peer_review.reviewee_id %>">
<%= form_for peer_review, :html => { :method => "post" }, :remote => true do |f| %>
  <%= f.error_messages %>
  <p>
    Peer Review for: <%= User.find(peer_review.reviewee_id).name %><br />
  </p>
  <p>
    <%= f.label :rating %>: 
    <%= f.select :rating, [1, 2, 3, 4, 5], { :include_blank => 'None' } %>
  </p>
  <p>
    <%= f.label :review %><br />
    <%= f.text_area :review %>
  </p>

  <%= f.hidden_field :user_id, :value => peer_review.user_id %>
  <%= f.hidden_field :reviewee_id, :value => peer_review.reviewee_id %>
  <%= f.hidden_field :review_period_id, :value => peer_review.review_period_id %>

  <p><%= f.submit "Submit" %></p>
<% end %>
</div>

js.erb:

$("#completed_peer_reviews").html("<%= escape_javascript(render('completed_peer_reviews')) %>");

我希望只是在js.erb文件中添加另一行,删除刚刚触发执行js.erb文件的表单元素,如下所示:

$("#peer_review_form_<%= peer_review.reviewee_id %>").remove();

我应该如何在这里引用peer_review.reviewee_id?或者我应该采取完全不同的方法吗?

1 个答案:

答案 0 :(得分:3)

这是RJS模板的经典问题之一。

快速回答:

如果您只是想解决问题,可以传递一些临时ID来识别表单。 e.g:

# in the index
<% @peer_reviews.each.with_index do |peer_review, i| %>
  <%= render :partial => 'form', 
             :locals  => { :peer_review => peer_review, :i => i } %>
<% end %>

# then in the form (note, you don't need to specify POST in a form_for)
<div id="peer_review_form_<%= i %>">
  <%= form_for peer_review, :remote => true do |f| %>
    <%= hidden_field_tag 'temp_id', i %>

# finally in the create js.erb
$("#peer_review_form_<%= params[:temp_id] %>").remove();

更长的答案:

这就是说,而RJS模板是&#34; Rails方式&#34;很长一段时间以来,他们都失宠了。

更现代的方法通常是带有JSON API的客户端JS模板,而不是运行服务器生成的JS模板(RJS)。这有很多优点,其中之一就是您现在不再存在的DOM绑定问题。

这是一个如何使用纯jQuery执行此操作的示例,但有许多模板选项。

<script id="peer_review_tmpl" type="text/x-jquery-tmpl">
  <div class="completed_peer_review">
    <p>${review}</p>
    ...
  </div>
</script>

然后,您将创建一个处理程序并将其绑定到成功的ajax响应。这需要您的peer_reviews#create操作响应JSON:

$('form.new_peer_review').bind("ajax:success", function(data) {
  // remove the form which triggered the creation        
  $(this).remove();

  // then render the data into a template, and append it to the list
  $("#peer_review_tmpl").tmpl(data).appendTo("#completed_peer_reviews"); 
});