【问题标题】:Rails: How can I render a block with ajax?Rails:如何使用 ajax 渲染块?
【发布时间】:2014-12-09 19:28:28
【问题描述】:

我有一个模型“事物”,它有_许多“评论”。我希望@thing.cmets 列表在按下“发表评论”按钮时使用 ajax 刷新。

此代码用于列出第一条评论的文本:

查看

<script type="text/javascript">
  $("#post").click(function () {
    $.get( "<%= postcomment_thing_path(:id => @thing.id) %>", function( data ) {
      $('#comments_h2').html(data);
    });
  });
</script>

控制者:

def postcomment
  @thing = Thing.find(params[:id])
  render text: @thing.comments.first.text.to_s
end

但是当我尝试打印整个注释块时,它只打印一个“#”。

控制者:

def postcomment
  @thing = Thing.find(params[:id])
  render text:
    @thing.comments.each do |comment|
      comment.text.to_s
    end
end

如何打印所有 cmets 的文本?

【问题讨论】:

  • 尝试将 each 替换为 map 并使用连接来组合结果。 @thing.comments.map { |comment| comment.text.to_s }.joins("&lt;br&gt;")
  • 它返回“未定义的局部变量或方法“注释””,你确定这是正确的语法吗?
  • 是的。但我确实有一个错误@thing.cmets.map { |comment| comment.text.to_s }.join("
    ")。应该是加入,而不是加入。另一件事,我会使用 render_to_string 而不是 render :text,但这是一个偏好问题。
  • 你知道它为什么会返回那个错误吗?

标签: ruby-on-rails ruby ajax ruby-on-rails-4 controller


【解决方案1】:

当发布新的 cmets 时,您不需要加载所有 cmets,您可以使用 rails 加载旧的 cmets 并显示它们,然后使用 ajax 将新的 cmets 添加/添加到旧的列表中。

我假设你的 cmets 在一个 div 中:

<div class="comments">
  <% @thing.comments.each do |comment| %>
    <div class="comment_<%= comment.id %>">
      <%= comment.content %>
    </div>
  <% end %>
</div>

您添加评论的表单应该有remote: true:

<%= form_for @comment, remote: true do |f| %>
   inputs here
<% end %>

当您添加评论时,我假设正在调用的是 action create,因此您需要 app/views/comments/ 文件夹中的 create.js.erb 文件和同一位置中的 _comment.html.erb

create.js.erb 将包含您的 js 代码,该代码会将注释附加/前置到 div.comments 元素:

<% if @comment.valid? %>  // @comment should be loaded in controller create action.
  $('div.comments').append("<%= j(render(@comment)) %>");
  $("#new_comment")[0].reset();
<% else %>
  alert("Can't add comment");
<% end %>

【讨论】:

  • _comment.html.erb 包含什么?
  • 评论内容,例如&lt;%= @comment.content %&gt;
【解决方案2】:

您应该在“发表评论”按钮中添加一个“remote: true”。从那里,你可以让你的控制器 response_to |format|并实时更新数据。

有关在 Rails 中使用 ajax 的更多信息,请参阅 here

【讨论】:

    【解决方案3】:

    好吧,虽然按照@rmagnum2002 的建议再次显示所有 cmets 并不是一个好主意。您应该根据您的要求附加或附加当前评论。但是,要使当前代码正常工作,您必须进行一些更改

    def postcomment
      @thing = Thing.find(params[:id])
      comment_text = ""
      @thing.comments.each do |comment|
         comment_text += comment.text.to_s
       end 
      # you could use map and join them by a delimiter also 
      render text: comment_text        
    end
    

    这应该呈现你所期望的。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 2019-09-25
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多