如何在ajax POST请求成功后呈现rails部分?

时间:2022-10-08 13:13:09

Problem: Partial does not update after ajax post request. Create.js.erb does not execute. I have added a console.log message to this file and it never appears in the console.

问题:部分在ajax post请求后不会更新。Create.js。erb不执行。我添加了一个控制台。将消息记录到这个文件中,它永远不会出现在控制台中。

After submitting the form, I look at the logs and see the post was successfully created:

提交表格后,我查看日志,看到帖子被成功创建:

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)

Run's Controller

运行的控制器

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

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?..");

Run Creation Form

运行创建表单

<%= 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 %>

Here's what I know:

这是我所知道的:

  • the form is set to data-remote="true" so the form is handled by JS
  • 表单被设置为data-remote="true",所以表单是由JS处理的。
  • the form is submitted as POST request to the /runs route
  • 该表格作为邮寄请求提交到/run路由
  • the runs controller is set to respond_to ajax
  • run控制器被设置为respond_to ajax
  • the create.js.erb file should automatically be called since the controller is set to handle JS.
  • create.js。应该自动调用erb文件,因为控制器被设置为处理JS。

Here's what has me slightly confused:

这就是我有点困惑的地方:

  • Do I need an .ajax method if I have a create.js.erb file? Other SO questions mention setting the dataType = "script". To the best of my knowledge, I should not need this file. For example:

    如果我有一个create.js,我需要一个。ajax方法吗?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
      });
    };
    
  • When I try to use the js above, the post request returns a 500 error when dataType is set to script. It works properly if I set the dataType to json, yet the partial still does not render.
  • 当我尝试使用上面的js时,如果将数据类型设置为脚本,post请求将返回500个错误。如果我将数据类型设置为json,它就可以正常工作,但是部分仍然没有呈现。

Sources I have consulted (I don't have enough reputation to post ALL the links):

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

I've spent a good amount of time on this before posting here. If anyone can point me in the right direction, I'll be a happy man. Thanks for reading.

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

3 个解决方案

#1


1  

You need to set your controller up to respond to JS. Remember that js != json.

您需要设置控制器来响应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

Not passing a block will trigger the rails default behaviour of rendering create.erb.js.

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

Do I need an .ajax method if I have a create.js.erb file?

如果我有一个create.js,我需要一个。ajax方法吗?erb文件?

No. You're using the Rails UJS driver to send an ajax request already. Otherwise the response type in the log would be :html.

不。您已经在使用Rails UJS驱动程序发送ajax请求。否则,日志中的响应类型为:html。

Other SO questions mention setting the dataType = "script". To the best of my knowledge, I should not need this file.

其他SO问题包括设置dataType = "script"。据我所知,我不需要这个文件。

You're correct. Rails UJS defaults to using a javascript accept type header. Its only if you want a JSON response for example that you need to set the dataType.

你是正确的。Rails UJS默认使用javascript接受类型头。它只适用于需要设置数据类型的JSON响应。

#2


1  

Your controller is missing format.js. Rails will look for it when you make an AJAX request.

您的控制器缺少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

#3


1  

Just try this in your controller's create method:

在控制器的创建方法中尝试一下:

 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

We need to specify a format to render. You didn't specify js format. when format.js is found empty rails checks if a file of methods name exists and render that js. create.js.erb in this case. You can also specify other file as:

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

format.js { render "some_other_jserb_file"}

Hope this helps..

希望这可以帮助. .

#1


1  

You need to set your controller up to respond to JS. Remember that js != json.

您需要设置控制器来响应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

Not passing a block will trigger the rails default behaviour of rendering create.erb.js.

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

Do I need an .ajax method if I have a create.js.erb file?

如果我有一个create.js,我需要一个。ajax方法吗?erb文件?

No. You're using the Rails UJS driver to send an ajax request already. Otherwise the response type in the log would be :html.

不。您已经在使用Rails UJS驱动程序发送ajax请求。否则,日志中的响应类型为:html。

Other SO questions mention setting the dataType = "script". To the best of my knowledge, I should not need this file.

其他SO问题包括设置dataType = "script"。据我所知,我不需要这个文件。

You're correct. Rails UJS defaults to using a javascript accept type header. Its only if you want a JSON response for example that you need to set the dataType.

你是正确的。Rails UJS默认使用javascript接受类型头。它只适用于需要设置数据类型的JSON响应。

#2


1  

Your controller is missing format.js. Rails will look for it when you make an AJAX request.

您的控制器缺少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

#3


1  

Just try this in your controller's create method:

在控制器的创建方法中尝试一下:

 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

We need to specify a format to render. You didn't specify js format. when format.js is found empty rails checks if a file of methods name exists and render that js. create.js.erb in this case. You can also specify other file as:

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

format.js { render "some_other_jserb_file"}

Hope this helps..

希望这可以帮助. .