使用Rails 4,我想使用Ajax表单post:remote =>是的,我希望能够以json格式返回响应,以便在出现故障时可以使用任何错误消息。
表单帖子对我的控制器操作很好。控制器动作:
def create
@comment_hash = comment_params
@obj = @comment_hash[:commentable_type].constantize.find(@comment_hash[:commentable_id])
@comment = Comment.build_from(@obj, current_user.id, @comment_hash[:body])
respond_to do |format|
if @comment.save
if @comment_hash[:reply_to].to_i > 0
@parentcomment = Comment.find(@comment_hash[:reply_to].to_i)
@comment.move_to_child_of(@parentcomment)
end
format.js { render :template => "comments/create.js.erb", :status => :created }
else
format.js { render :template => "comments/create.js.erb", :status => :unprocessable_entity }
end
end
end
控制器操作将呈现create.js.erb,无论成功或错误如何。但是,如果我包含format.json,它将永远不会使用json响应。我认为这是因为Ajax remote:true请求将始终使用js进行响应。
如何获取响应json的ajax请求?
根据观察到rails ajax请求以js格式响应,我对此处提供的示例更加困惑:http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html其中成功的保存响应提供了js格式,但错误响应不提供任何js格式。
我认为这会导致ajaxError响应错误,因为js格式不可用?:
def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User was successfully created.' }
format.js {}
format.json { render json: @user, status: :created, location: @user }
else
format.html { render action: "new" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
答案 0 :(得分:7)
控制器操作将呈现create.js.erb,无论成功或错误如何。但是,如果我包含format.json,它将永远不会使用json响应。我认为这是因为Ajax remote:true请求将始终使用js
进行响应
首先,你的假设不正确。 Rails remote: true
挂钩到所谓的UJS驱动程序,这使得使XHR请求更简单所涉及的工作很多。但是,您可以通过form_for
或form_tag
来实现相同的行为,并通过jQuery的优秀$.ajax()
纯粹在JS中处理表单提交。
我建议你先删除create.js.erb
- 这将始终被处理以返回脚本响应,而你想要渲染JSON。
你也可以在这里更明确一点,
format.json { render json: { @user, status: :created, location: @user } }
在幕后,Rails在您的Ruby对象(如AR模型)上调用#to_json
到简单的哈希。
删除create.js.erb
后,转到呈现表单的视图。在DOM中查找form
元素,您可以通过检查器控制台通过$('form')
随便查找它。最好通过类或直接识别它的ID。我们假设您的表单选择器为$('#comments-form')
。
您需要将另一个JS文件添加到app/assets/javascripts/application.js
Sprockets清单中,并在该文件中
$(function(){
var $commentForm = $('#comments-form');
$commentForm.on('ajax:error', function(e, xhr, status, error) {
console.log('Error: %O', $(this).append(xhr.responseText));
});
$commentForm.on('ajax:success', function(e, data, status, xhr) {
console.log('Data: %O', data);
});
});
上面的JS片段是一个开始,当触发那些jquery-ujs events时将触发,将调试输出放入控制台。在XHR错误上,您将获得错误信息,成功时将显示JSON数据。
<强>附录强>:
respond_to块中的format.js
纯粹用于处理create.js.erb
,在提供的示例中执行此操作$("<%= escape_javascript(render @user) %>").appendTo("#users");
- 它使用用户实例来确定DOM选择器,并且将其添加到ID为'users'的DIV中。
就个人而言,我发现通过成功处理程序坚持使用JSON并通过成功处理程序实现相同的行为更简单,尽管是YMMV。