成功的ajax POST请求后如何渲染rails部分?

时间:2017-04-11 16:59:42

标签: ruby-on-rails ajax erb

问题:在ajax发布请求后,部分不会更新。 Create.js.erb不执行。我已将console.log消息添加到此文件中,并且它永远不会出现在控制台中。

提交表单后,我查看日志并看到帖子已成功创建:

Started POST "/runs" for 127.0.0.1 at 2017-04-11 08:57:25 -0700
  Processing by RunsController#create as JS
    Parameters: {"utf8"=>"✓", "run"=>{"skater_id"=>"2", "competition_id"=>"31", "start_time"=>"1", "stop_time"=>"2", "score"=>"5", "best_trick"=>"0"}, "commit"=>"Create Run"}
    User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 5]]
     (0.1ms)  begin transaction
    SQL (0.3ms)  INSERT INTO "runs" ("start_time", "stop_time", "skater_id", "competition_id", "score", "best_trick", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?)  [["start_time", 1], ["stop_time", 2], ["skater_id", 2], ["competition_id", 31], ["score", 5.0], ["best_trick", "f"], ["created_at", "2017-04-11 15:57:25.602458"], ["updated_at", "2017-04-11 15:57:25.602458"]]
     (2.0ms)  commit transaction
  Completed 200 OK in 5ms (Views: 0.3ms | ActiveRecord: 2.4ms)

运行控制器

def create
  @run = Run.new(run_params)
  @runs = Run.all
  respond_to do |format|
    if @run.save
      format.json { render json: @runs }
      format.html { redirect_to :back, :notice => 'Run was successfully created.' }
    else
      format.html { render action: "new" }
      format.json { render json: @run.errors, :status => :unprocessable_entity }
    end
  end
end

create.js.erb

$("#run-breakdown").html("<%= escape_javascript(render partial: 'runs/run') %>");

/* let's check and see if this is executing */
console.log("Is this file being executed?..");

运行创建表单

<%= form_for(@run, remote: true, :html => {class:"form-horizontal", role: "form", id:"run-creation-form"}) do |x| %>
    <!-- FIELDS & STYLING REMOVED FOR BREVITY -->
    <%= x.submit class:"btn btn-primary" %>
<% end %>

以下是我所知道的:

  • 表单设置为data-remote =“true”,因此表单由JS
  • 处理
  • 表单作为POST请求提交给/ runs route
  • 运行控制器设置为respond_to ajax
  • 自动调用create.js.erb文件应该,因为控制器设置为处理JS。

这让我有点困惑:

  • 我是否需要.ajax方法如果我有一个create.js.erb文件?其他SO问题提到设置dataType =“script”。据我所知,我不应该需要这个文件。例如:

    $('#run-creation-form').submit(function() {
        var valuesToSubmit = JSON.stringify($(this).serialize());
        console.log(valuesToSubmit);
        $.ajax({
          type: "POST",
          url: '../runs/',
          data: valuesToSubmit,
          dataType: "script"
        }).success(function(data) {
          console.log(data);
          // $('#run-breakdown').html(data);
        }).error(function(error) {
          console.log(error);
        });
      return false; // prevents normal behaviour
      });
    };
    
  • 当我尝试使用上面的js时,当dataType设置为script时,post请求会返回500错误。如果我将dataType设置为json,但部分仍然不呈现,则它可以正常工作。

我咨询的来源(我没有足够的声誉发布所有链接):

我在这里发布之前花了很多时间。如果有人能指出我正确的方向,我将是一个快乐的人。谢谢你的阅读。

3 个答案:

答案 0 :(得分:1)

您需要设置控制器以响应JS。请记住js != json

def create
  @run = Run.new(run_params)
  @runs = Run.all
  respond_to do |format|
    if @run.save
      format.json { render json: @runs }
      format.html { redirect_to :back, :notice => 'Run was successfully created.' }
      format.js
    else
      format.html { render action: "new" }
      format.json { render json: @run.errors, :status => :unprocessable_entity }
      format.js { render action: "new" }
    end
  end
end

不传递块将触发渲染create.erb.js的rails默认行为。

  

如果我有create.js.erb文件,是否需要.ajax方法?

没有。您已经使用the Rails UJS driver发送了ajax请求。否则,日志中的响应类型将为:html

  

其他SO问题提到设置dataType =&#34;脚本&#34;。据我所知,我不应该需要这个文件。

你是对的。 Rails UJS默认使用javascript accept类型标头。仅当您需要JSON响应时才需要设置dataType。

答案 1 :(得分:1)

您的控制器缺少format.js。当您发出AJAX请求时,Rails会查找它。

respond_to do |format|
    if @run.save
     format.html { redirect_to :back, :notice => 'Run was successfully created.' }
     format.json { render json: @runs }
     format.js
    else

答案 2 :(得分:1)

只需在控制器的创建方法中尝试:

 respond_to do |format|
    if @run.save
      format.json { render json: @runs }
      format.html { redirect_to :back, :notice => 'Run was successfully created.' }
      format.js {}
    else
      format.html { render action: "new" }
      format.json { render json: @run.errors, :status => :unprocessable_entity }
   end
  end

我们需要指定要渲染的格式。你没有指定js格式。当找到format.js时,空rails检查是否存在方法名称的文件并呈现该js。在这种情况下create.js.erb。您还可以将其他文件指定为:

format.js { render "some_other_jserb_file"}

希望这会有所帮助..