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

9
我希望通过 AJAX 更新表单提交,而不需要重新加载页面,并根据更新的结果更新视图。我尝试了不同的方法,但由于我是新手,所以失败了。

以下是情况说明:

在模态框中。

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更新,但每次都失败了。有人可以帮忙吗?先谢谢了。


你尝试了什么?请在这里发布。 - Deepesh
嗨@Deep,我有一个表单,它只是从用户那里获取标题并将其更新到数据库中,并在下面显示标题数量。我不想在表单提交时重新加载页面。因此,我想使用AJAX来完成它。 - Praveen KJ
4个回答

17

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

  1. 你需要在表单中添加remote=true

    <%= form_for(@image,:html=>{:id=>"your_form_id",:multipart => true,:remote=>true}) do |f |%>

  2. 此外,在服务器端,你需要创建一个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  
  1. show_updated_view.js.erb文件中,您应该更新视图,以便用户知道视图已更新或表单已成功提交,可以通过隐藏整个表单/重置表单或用新的div替换表单来实现,显示提示数据已更新的消息或任何直观的方式。当然有很多种方法 :)

    //这里我将整个表单替换为一个包含消息的div

    $("#your_form_id").html("<div><p>您已成功提交表单。</p></div>");

视图的名称可以是任何名称,但您需要同时考虑成功和失败的情况。


4

这里是关于使用Rails做AJAX的简短文章。需要注意以下几点:

  1. 在你的form_for中添加remote: true
  2. 在你的控制器中包含format.js,以便它将呈现create.js.erb
  3. create.js.erb中,可以像这样做(未经测试):

    $("p.instructions").innerHTML("<%= @notes_list %>")


嗨Yen-Ju,这是整个视图页面<%= form_for @new_entry, :html => {:class => 'home-form without-entry clearfix'}, remote: true do |f| %> <%= f.text_field :title, placeholder: 'Squirrel', autofocus: true, class: 'title-field pull-left' %> <%= f.submit '', class: 'btn home-add without-entry' %> <% end %><div class="col-xs-12 content-box" id="content-box"> <p class="instructions count-instruction text-center"> <%= @words.count %> </p></div> 那么我在create.js.erb中想做什么? - Praveen KJ
仅替换底部的 content-box div? - Praveen KJ

0
记住AJAX的一件事就是通常不会重定向请求,而是生成一些文本发送回浏览器。 AJAX基本上只是JavaScript,用于从浏览器获取一些文本并对其进行操作。通常,您希望替换页面的某个部分,即将HTML标记及其内容替换为返回的文本,在这种情况下,您需要的文本应该是一些HTML。 在Rails中呈现一个HTML块的方法是呈现partial,所以您可以这样做,并且通常还要执行一些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请求。 - Deepesh

0
尝试在你的控制器动作“create”中添加respond_to block,并分别创建create.js.erb文件,在其中放置你想要在create操作之后执行的js代码,如果你在浏览器控制台或rails服务器控制台上遇到任何错误,请将其提交,以便我们帮助你找出问题所在。

嗨@Suman ghosh,如之前所述,我是Rails的新手。我已经使用了remote:true更新了数据库。我想知道如何使用respond_to显示更新后的内容,因为我以前从未使用过它。<div class="col-xs-12 content-box" id="content-box"><%= @words.count %></div>。我想在ajax提交时每次更改计数。所以你能帮我处理一下那个respond_to部分吗? - Praveen KJ
format.html { redirect_to :back } format.js 这段代码想要实现什么功能? - Praveen KJ
@PraveenKJ,你非常接近成功了,你只需要编写一个create.js.erb文件,在创建新记录后更新<p>标签的内容即可。所以在这里,您需要为要更新其内容的<p>元素添加一个id,比如说 <p id="words-count" class="instructions count-instruction text-center"> <%= @words.count %> </p>,然后在create.js.erb中使用$('#words-count').html("<%= @words_count %>");(假设您已经在操作中分配了单词计数)。 - sghosh968

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接