Rails 通过 ajax 提交表单并更新视图

Posted

技术标签:

【中文标题】Rails 通过 ajax 提交表单并更新视图【英文标题】:Rails submitting a form through ajax and updating the view 【发布时间】:2015-09-27 12:28:33 【问题描述】:

我想通过 ajax 更新表单提交而不重新加载页面并根据它更新视图。我尝试了不同的方法,但由于我是 Rails 新手而失败了。

情况是这样的。

在模态中

def new
    @new_entry = current_user.notes.build
    @words = current_user.notes
    @notes_false_list = current_user.notes.where(known: false).order("title").group_by  |note| note.title[0] 
    @notes_true_list = current_user.notes.where(known: true).order("title").group_by  |note| note.title[0] 
  end

在查看表单代码。

<%= form_for @new_entry, :html => :class => 'home-form without-entry clearfix'  do |f| %>
      <%= f.text_field :title, placeholder: 'Squirrel', autofocus: true, class: 'title-field pull-left' %>
      <%= f.submit '', class: 'btn home-add without-entry' %>
  <% end %>

创建动作

def create
    @new_note = current_user.notes.build(new_note_params)
    if @new_note.save
      @notes_list = current_user.notes.count
      unless @new_note.user.any_entry
        @new_note.user.toggle!(:any_entry) if @notes_list >= 50
        redirect_to root_url
      end
    else
      redirect_to root_url
    end
  end

最后在我想要改变的视图中

<p class="instructions count-instruction text-center">
      <%= @words.count %>
    </p>

花了很多时间用 AJAX 更新它,但每次都失败了。有什么可以帮忙的吗?提前致谢。

【问题讨论】:

您尝试了什么,请在此处发布? 嘿@Deep 好吧,我有一个表单,它只是从用户那里获取标题并在数据库上更新它,并且在下面显示没有标题计数。我不想在提交表单时重新加载页面。所以我想用 AJAX 来做。 【参考方案1】:

你的代码很好,但是对于 ajax

    您需要在表单中添加remote=true

    &lt;%= form_for(@image,:html=&gt;:id=&gt;"your_form_id",:multipart =&gt; true,:remote=&gt;true) do |f |%&gt;

    此外,在您的服务器端,您需要在其中创建一个 js.erb 文件 views/users/show_updated_view.js.erb 作为 js 回复浏览器 调用而不是 html 调用,因此需要向用户显示表单提交后发生的事情(成功/错误)(如果是 users_controller),

所以在你的行动中,你需要这样的东西:-

        respond_to do |format|  
            format.js  render 'users/show_updated_view'
        end  

    show_updated_view.js.erb 中,您应该为用户更新您的视图 知道视图已更新或表单已成功 通过隐藏整个表单/重置表单或 用新的 div 替换表单,表示数据已更新..或任何直观的东西。不过有很多方法:)。

    //这里我用带有消息的 div 替换你的整个表单

    $("#your_form_id").html("&lt;div&gt;&lt;p&gt;You have submitted the form successfully.&lt;/p&gt;&lt;/div&gt;");

视图的名称可以是任何名称,但您需要兼顾成功和失败。

【讨论】:

【参考方案2】:

这是short article on doing AJAX with Rails。需要注意的几点:

    在您的form_for 中添加remote: true。 在您的控制器中包含 format.js,以便它呈现 create.js.erb

    create.js.erb 中,执行如下操作(未测试):

    $("p.instructions").innerHTML("&lt;%= @notes_list %&gt;")

【讨论】:

Hey Yen-Ju 这是整个视图页面 &lt;%= form_for @new_entry, :html =&gt; :class =&gt; 'home-form without-entry clearfix', remote: true do |f| %&gt; &lt;%= f.text_field :title, placeholder: 'Squirrel', autofocus: true, class: 'title-field pull-left' %&gt; &lt;%= f.submit '', class: 'btn home-add without-entry' %&gt; &lt;% end %&gt; &lt;div class="col-xs-12 content-box" id="content-box"&gt; &lt;p class="instructions count-instruction text-center"&gt; &lt;%= @words.count %&gt; &lt;/p&gt; &lt;/div&gt; 那么我想在 create.js.erb 中做什么? 单独替换底部的content-box div?【参考方案3】:

使用 AJAX 要记住的是,您不会重定向请求(通常),您只需生成一些文本以发送回浏览器。 AJAX 基本上只是 javascript 从浏览器获取一些文本并对其进行处理。通常,您会希望用您返回的文本替换页面的一部分,即替换一个 html 标记及其内容,在这种情况下,您希望文本是一些 html。在rails中渲染一大块html的方法是渲染一个部分,所以你这样做,你也经常做一些javascript来告诉浏览器如何处理文本,通常是用一个特定的id替换一个元素文本。

def create
  @new_note = current_user.notes.build(new_note_params)
  if @new_note.save 
    @notes_list = current_user.notes.count
    unless @new_note.user.any_entry
      @new_note.user.toggle!(:any_entry) if @notes_list >= 50
    end
  end
  respond_to do |format|
    format.html  redirect_to root_url 
    format.js #default behaviour is to run app/views/notes/create.js.erb file
  end
end

这里的 respond_to 块允许您以不同的方式处理 html 和 js(例如 ajax)请求。

app/views/notes/create.js.erb 可能有类似

page.replace "foo", :partial => "app/views/notes/bar"

【讨论】:

请在表单中添加remote: true,否则它将始终发送 HTML 请求【参考方案4】:

尝试在您的控制器操作“create”中添加respond_to block,并在相应的 create.js.erb 中添加您想要在创建操作后执行的 js,并发布您遇到的任何错误浏览器控制台或 Rails 服务器控制台,这样做我们可以帮助您找到错误的地方

【讨论】:

嗨@Suman ghosh,如前所述,我是Rails 新手。我做了直到更新数据库的 remote:true 。我想知道如何用 respond_to 显示更新的内容,因为我以前从未使用过它。 &lt;div class="col-xs-12 content-box" id="content-box"&gt;&lt;%= @words.count %&gt;&lt;/div&gt; 。我想每次在 ajax 提交时更改计数。那么你能帮我处理一下respond_to部分吗? format.html redirect_to :back format.js 那么我想在这个部分做什么呢? @PraveenKJ 你非常接近,你只需要编写一个 create.js.erb 文件,在创建新记录后更新

标签的内容。所以在这里你必须为

元素添加一个 id 到你想要更新的内容让我们说&lt;p id="words-count" class="instructions count-instruction text-center"&gt; &lt;%= @words.count %&gt; &lt;/p&gt; 和 create.js.erb => $('#words-count').html("&lt;%= @words_count %&gt;");(假设你在你的行动中分配了字数)跨度>

以上是关于Rails 通过 ajax 提交表单并更新视图的主要内容,如果未能解决你的问题,请参考以下文章

文档准备好后通过 Ajax 加载的 Rails 远程表单未提交

Rails/Ajax 在提交后将表单从创建更改为更新

通过 ajax rails 2 向 rails 3 提交表单

Rails 5 ajax 表单:单击 Ajax 中的 2 个单选按钮之一提交表单

Rails - 如何在不更改页面和更新视图的情况下提交表单?

Jquery 表单提交无法使用 AJAX 和 Rails 莫名其妙地重新渲染 index.html.erb