Rails Ajax JS与JSON混淆

时间:2015-07-30 23:40:13

标签: javascript ruby-on-rails ajax json

使用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进行响应。

  1. 如何获取响应json的ajax请求?

  2. 根据观察到rails ajax请求以js格式响应,我对此处提供的示例更加困惑:http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html其中成功的保存响应提供了js格式,但错误响应不提供任何js格式。

  3. 我认为这会导致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
    

1 个答案:

答案 0 :(得分:7)

  

控制器操作将呈现create.js.erb,无论成功或错误如何。但是,如果我包含format.json,它将永远不会使用json响应。我认为这是因为Ajax remote:true请求将始终使用js

进行响应

首先,你的假设不正确。 Rails remote: true挂钩到所谓的UJS驱动程序,这使得使XHR请求更简单所涉及的工作很多。但是,您可以通过form_forform_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。