【问题标题】:AJAX Ruby on Rails | partial not re-renderingAJAX Ruby on Rails |部分不重新渲染
【发布时间】:2019-01-06 00:49:49
【问题描述】:

您好,我对 Rails 还很陌生,正在尝试在我的 Rails 应用程序中实现 AJAX。

问题是,当我提交表单时,似乎肯定调用了创建操作,因为当我刷新页面时会出现新元素,但表格不会自动刷新。

topics/show.html.erb相关代码:

<div class="row" id="toberefreshed">
  <%= render('show_partial', :locals => {:topic => @topic}) %>
</div>

topics/_show_partial.html.erb相关代码:

<table class = "opinionlist" align="center">
  <% opinions = @topic.opinions %>
  <% cons = opinions.select{|opinion| opinion.type_of == 'con'} %>
  <% pros = opinions.select{|opinion| opinion.type_of == 'pro'} %>
  <tr>
    <% pros.each do |pro|%>
      <td>
        <div class="article-body">
          <%= pro.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= pro.user.username %>
            <%= time_ago_in_words(pro.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length < cons.length %>
      <% difference = cons.length - pros.length%>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>

    <td><%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => @topic %></td>
  </tr>
  <tr>
    <% cons.each do |con|%>
      <td>
        <div class="article-body">
          <%= con.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= con.user.username %>
            <%= time_ago_in_words(con.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length > cons.length %>
      <% difference = pros.length - cons.length %>
      <%  puts "DIFFERENCE: " + difference.to_s  %>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>
    <td>
      <%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => @topic %>
    </td>
  </tr>
</table>

主题/updated_view.js.erb:

$("toberefreshed").html("<%= escape_javascript(render("topics/show_partial", :locals => {:topic => @opinion.topic})) %>");

opinions_controller.rb

class OpinionsController < ApplicationController
  def create
    @opinion = Opinion.new(opinion_params)
    @opinion.user = current_user
    @opinion.topic = Topic.find(params[:to_find_id])
    @opinion.type_of = params[:type_of]
    if @opinion.save
      flash[:success] = 'Opinion Added'
    else
      puts @opinion.errors.full_messages
      flash[:danger] = 'Opinion not Added'
    end
    respond_to do |format|
      format.js
    end
  end
  private
  def opinion_params
    params.require(:opinion).permit(:content)
  end
end

编辑:意见/_form.html.erb

<div class="row">
  <div class="col-xs-12">
    <%= form_for(opinion, :html=> {class:"form-horizontal", role:"form"}, remote: true) do |f| %>
      <div class="form-group">
        <div class="col-sm-12">
          <%= f.text_area :content, rows:4, class: "form-control", placeholder: "Opinion" %>
        </div>
      </div>
      <%= hidden_field_tag 'type_of', typeOf %>
      <%= hidden_field_tag :to_find_id, @topic.id %>
      <% puts "ID: " + @topic.id.to_s %>
      <div class="form-group">
        <div class="col-sm-12">
          <%= f.submit %>
        </div>
      </div>
    <% end %>
  </div>
</div>

非常感谢您的帮助, 拉希尔

【问题讨论】:

  • 请把opinions/_form.html.erb的内容发一下好吗?
  • @ViktorNonov 是的,它现在应该在那里。抱歉忘记了...
  • @Raail Jain,谢谢,opinions/create.js.erb 也会有所帮助。
  • 将 updated_view.js.erb 重命名为 create.js.erb
  • 应该在意见文件夹中吗?还是主题文件夹?

标签: ruby-on-rails ruby ruby-on-rails-5 rails-ujs


【解决方案1】:

topics/_show_partial.html.erb

替换

&lt;% opinions = @topic.opinions %&gt; 在第二行

&lt;% opinions = topic.opinions %&gt;

您正在通过局部变量将 topic 变量传递给部分,但您正在调用 instance variable @topic,当您调用 create 方法时该变量不存在

同时更改以下内容:

&lt;%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic =&gt; @topic %&gt;

&lt;%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic =&gt; topic %&gt;


然后改变

<%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => @topic %>

&lt;%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic =&gt; topic %&gt;


所以你的topics/_show_partial.html.erb 应该如下所示:

<table class = "opinionlist" align="center">
  <% opinions = topic.opinions %>
  <% cons = opinions.select{|opinion| opinion.type_of == 'con'} %>
  <% pros = opinions.select{|opinion| opinion.type_of == 'pro'} %>
  <tr>
    <% pros.each do |pro|%>
      <td>
        <div class="article-body">
          <%= pro.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= pro.user.username %>
            <%= time_ago_in_words(pro.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length < cons.length %>
      <% difference = cons.length - pros.length%>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>

    <td><%= render 'opinions/form', opinion: Opinion.new, typeOf: "pro", :topic => topic %></td>
  </tr>
  <tr>
    <% cons.each do |con|%>
      <td>
        <div class="article-body">
          <%= con.content %>
        </div>
        <div class="article-meta-details">
          <small>
            Created by: <%= con.user.username %>
            <%= time_ago_in_words(con.created_at) %> ago,
          </small>
        </div>
      </td>
    <% end %>
    <% if pros.length > cons.length %>
      <% difference = pros.length - cons.length %>
      <%  puts "DIFFERENCE: " + difference.to_s  %>
      <% difference.times do %>
        <%= content_tag(:td) %>
      <% end %>
    <% end %>
    <td>
      <%= render 'opinions/form', opinion: Opinion.new, typeOf: "con", :topic => topic %>
    </td>
  </tr>
</table>

您可以作为建议的最后一件事:

您正在视图中构建大量逻辑,例如topics/_show_partial.html.erb 您在视图中创建了大量局部变量。我建议使用另一种方法,例如在视图之前的层中构建所有变量,例如 presenters 查看有关 rails presenters 的讨论

What is the Rails Presenters folder for?

Views 应该尽可能保持简单和没有逻辑

【讨论】:

  • 当我这样做时会发生这种情况:显示/topics/_show_partial.html.erb where line #2 raise: undefined local variable or method `topic' for #:0xce8af88>你的意思是? @主题
  • 不看文档以了解如何将局部变量传递给视图 guides.rubyonrails.org/…
  • 好的,此时我的渲染语句如下所示:render partial: "topics/show_partial", locals: {topic: @opinion.topic} 这是正确的吗?我还将 js 文件重命名为 create.js.erb 并将其移至 Vasilisa 建议的意见。它似乎仍然没有替换我的表的内容,但我不再收到未定义的局部变量或方法错误。
猜你喜欢
  • 2017-05-07
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多