rails:在js.erb中访问非实例变量 [英] rails: accessing a non-instance variable in js.erb

查看:108
本文介绍了rails:在js.erb中访问非实例变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a page that renders multiple forms. Currently, when the user submits any one of these forms, it updates (via ajax) a div on the same page with the content from the form that was just submitted.

我还想删除()在ajax发布请求完成后刚刚提交的form元素.但是,我需要能够访问js.erb文件中的特定表单ID.

I also want to remove() the form element that was just submitted after the ajax post request is completed. However, I need to be able to access that specific form ID within the js.erb file to do so.

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

Since my page has x number of forms rendered dynamically, I cannot simply access an instance variable in my 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>

@peer_reviews实例变量包含一个已经包含一些数据的新PeerReview对象的数组.

The @peer_reviews instance variable contains an array of new PeerReview objects already containing some data.

表格:

<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文件执行的form元素,如下所示:

I was hoping to just add another line to the js.erb file that removes the form element that just triggered the execution of the js.erb file like so:

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

实际上我应该如何在这里引用peer_review.reviewee_id?还是我应该采取一种完全不同的方法?

How should I actually be referencing peer_review.reviewee_id here? Or should I be taking a completely different approach?

推荐答案

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

This is one of the classic issues of RJS templates.

如果仅想解决问题,则可以传递一些临时ID来标识表单.例如:

If you simply want to solve the problem, you could pass along some temporary id to identify the form. 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模板在很长一段时间内都是"Rails方式",但自那以后就不再受到青睐.


Longer Answer:

That being said, while RJS templates were "the Rails way" for a long time, they've since fallen out of favor.

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

The more modern method is typically client side JS templates with a JSON API, rather than running server generated JS templates (RJS). This has a lot of advantages, one being that the DOM binding issue you're having right now no longer exists.

这是一个示例,说明如何使用纯jQuery进行此操作,但是那里有许多模板选项.

This is an example of how you might do this with pure jQuery, but there are many templating options out there.

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

Then you'd create a handler and bind it to a successful ajax response. This would require that your peer_reviews#create action responded to 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"); 
});

这篇关于rails:在js.erb中访问非实例变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆