且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Rails:无法提交通过Ajax加载的远程表单

更新时间:2023-11-24 11:15:40

我发现了问题!感谢@Jake Smith和@Parandroid的答案中的提示.这是我通过两个步骤发现的.

I found the problem! Thanks to the hints in the answers of both @Jake Smith and @Parandroid. Here's what I found in two steps.

虽然触发ajax:success似乎不是问题,但确实看起来仅在$("#editor")选择器上,表单处理不能正确地100%正常工作.至少必须是$("#editor form"),但是如果我们从还不包含表单的索引页开始,那可能就行不通了.因此,@ Jake Smith建议的方法毕竟是最可靠的方法.结果是:

While getting the ajax:success to be fired did not seem to be the problem, it did look like the form handling did not work 100% correctly just on the $("#editor") selector. At the very least that needed to be $("#editor form"), but that might not work if we start from the index page, which doesn't contain the form yet. So the approach suggested by @Jake Smith seemed to be the most robust way to go after all. This resulted in:

edit.html.haml

#editor
  = render :partial => "edit"

edit.js.erb

$('#editor').html('<%= escape_javascript render("edit") %>');

_edit.html.haml(仍然无法运行)

%table
  - @items.each do |item|
    %tr
      - if item == @item
        = form_for @item, :url => item_path(@item), :remote => true, do |f|
          = render :partial => "row_form", :locals => { :f => f }
      - else
        = render :partial => 'row', :locals => { :item => item }

但是,这仍然没有导致提交按钮正常工作.直到我发现出了什么问题...

But still this did not result in a working submit button. Until I discovered what went wrong...

以上解决方案确实使提交按钮具有普通的POST行为,而服务器不喜欢这种行为,因为服务器希望PUT达到update动作. Rails通过生成值为PUT的隐藏的_method字段来做到这一点.我发现,rails在_edit.html.haml部分的顶部和form标签内的 not 的顶部中生成了该字段(以及其他一些重要的隐藏字段). !因此,我将表单移到了部分表单的顶部,并且成功了!

The solution above did give the submit button plain old POST behavior, which the server did not like, since it expected a PUT to reach the update action. Rails does this by generating a hidden _method field with the value PUT. I found out that rails generates this field (and a couple of other crucial hidden fields) on the very top of the _edit.html.haml partial and not inside the form tag! So I moved the form to the top of the partial and it worked!

_edit.html.haml(工作!)

= form_for @item, :url => item_path(@item), :remote => true, do |f|
  %table
    - @items.each do |item|
      %tr
        - if item == @item
          = render :partial => "row_form", :locals => { :f => f }
        - else
          = render :partial => 'row', :locals => { :item => item }

谁会猜到...