我有一个通过ajax呈现并通过ajax提交的表单。我面临的问题是ajax提交在第一次提交时不起作用但是当页面重新加载并且表单第二次呈现时提交会工作。
表格
<%= form_for(@address,:remote=>true) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :full_address %>
<%= f.text_area :full_address %>
<%= f.submit %>
<% end %>
处理保存的控制器方法是
def create
@address = Address.new(address_params)
@address.user_id=current_user.id
respond_to do |format|
if @address.save
format.html { redirect_to @address, notice: 'Address was successfully created.' }
format.json { render :show, status: :created, location: @address }
format.js
else
format.html { render :new }
format.json { render json: @address.errors, status: :unprocessable_entity }
format.js
end
end
end
的修改 在第一个XHR请求中我得到了表格
<input name="utf8" value="✓" type="hidden">
<div class="field">
<label for="address_name">Name</label><br>
<input name="address[name]" id="address_name" type="text">
</div>
<div class="field">
<label for="address_full_address">Full address</label><br>
<textarea name="address[full_address]" id="address_full_address"></textarea>
</div>
<div class="actions">
<button type="submit">Submit</button>
</div>
然而,在第二次请求中我得到了这个
<form class="new_address" id="new_address" action="/addresses" accept-charset="UTF-8" data-remote="true" method="post">
<input name="utf8" value="✓" type="hidden">
<div class="field">
<label for="address_name">Name</label><br>
<input name="address[nEditame]" id="address_name" type="text">
</div>
<div class="field">
<label for="address_full_address">Full address</label><br>
<textarea name="address[full_address]" id="address_full_address"></textarea>
</div>
<div class="actions">
<button type="submit">Submit</button>
</div>
</form>
答案 0 :(得分:0)
在有问题的控制器addresses_controller
的视图中,创建一个名为create.js.erb
的新文件。这是响应的目的地。
在此文件中,编写jquery代码
$('html_tag').html('<%=j render @address%>')
要替换的视图元素应具有类ID,或者您可以使用标记(
// ...)选择它。
如果您不熟悉jquery,请尝试使用此网站。
答案 1 :(得分:0)
您的问题听起来就像JQuery委派问题一样。
大多数人直接将JQuery绑定到元素;此绑定仅在DOM加载时发生,这意味着任何新元素都没有附加功能:
#app/assets/javascripts/application.js
$("element").on("click"....
只有你拥有&#34;元素&#34;在DOM加载时定义,并在$(document).ready
块中调用此函数。
-
如果在 DOM加载后加载元素,则需要确保JQuery可以绑定到它们。过去曾使用.live
处理,但现在使用.on
:
#app/assets/javascripts/application.js
$(document).on("click", ".element"...
以上用于将事件绑定到DOM之后加载的元素。它来自document
对象的委托,它允许您的JQuery绑定到您需要的任何元素。
简而言之,如果您正在使用加载了ajax的元素,则应始终绑定到document
,并委托给动态元素。
remote:true
由于您正在使用remote: true
,因此我们必须了解Rails如何处理JS委派。
从rails.js
github page可以看出,似乎Rails通过document
绑定其事件处理程序:
$document.delegate(rails.buttonClickSelector, 'click.rails', function(e) {
虽然这似乎没问题,但我认为有一些东西阻止它绑定到动态加载的表单。
我会试试这个:
<%= form_for @address, id: "address" do |f| %>
#app/assets/javascripts/application.js
$(document).on("submit", "form#address", function(e){
$.post($(this).attr("action"), $(this).serialize());
});
目的是删除remote: true
引用,将我们自己的JS绑定到文档&amp;委托动态加载的表单。
它仍会提供XHR请求,从而保持应用程序的流量。