Rails 4使用ajax、jquery、:remote => true和respond_to。

时间:2022-10-08 14:15:08

It seems like rendering a page dynamically with AJAX in response to a submitted form is common. None of the other similar questions are focused around how to do this in a general way.

似乎使用AJAX动态呈现页面以响应提交的表单是很常见的。其他类似的问题都没有集中在如何以一种通用的方式实现这一点上。

The best blog post I could find on the subject was here: http://www.gotealeaf.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails

关于这个话题,我能找到的最好的博客文章是:http://www.gotealeaf.com/blog/the detailed guide on- how-ajax-workwith -ruby-on-rails

The question: How do I code my rails application so that I can trigger a partial view to load via AJAX when I submit a form or click a link?

问题是:如何编写rails应用程序,以便在提交表单或单击链接时通过AJAX触发部分视图以加载?

3 个解决方案

#1


32  

Several things must be present for this to work, including the :remote => true flag on the triggering element, the respond_to :js flag in the controller's class definition, the route, the partial view, and lastly the jquery to actually render a dynamic partial must be contained in a separate .html.js file.

Examples below are for a fictitious "render_partial_form" method of the "someajax" controller.

要实现这一点,必须提供以下几样东西,包括:remote =>触发元素上的true标志、控制器类定义中的respond_to:js标志、路由、部分视图,以及实际呈现动态部分的jquery必须包含在一个单独的.html中。js文件。下面的例子是“someajax”控制器虚构的“render_partial_form”方法。


1) Add a :remote => true flag to the triggering element
put the :remote => true flag on the link or form tag in your .html.erb file (view) for the element that you want to trigger the AJAX call, like

1)在触发元素中添加:remote => true标志,将:remote => true flag放在链接上,或在.html中form标记。对于想要触发AJAX调用的元素,erb文件(视图)。

<%= form_tag("/someajax", method: 'post', :remote => true) do %>

with :remote => true, rails will not automatically switch views, which allows the JQuery to be run instead. This can be used with a form_tag, a link_tag, or other types of tags.

使用:remote =>确实,rails不会自动切换视图,这允许JQuery运行。这可以与form_tag、link_tag或其他类型的标记一起使用。


2) Add "respond_to :html, :js" at the top of the controller

At the top of your controller's class definition, you must now specify that the controller can respond to javascript as well as html:

2)在控制器类定义的顶部添加“respond_to:html,:js”,现在必须指定控制器既可以响应javascript,也可以响应html:

class SomeajaxController < ApplicationController
   respond_to :html, :js

   ...

   def render_partial_form
      @array_from_controller = Array.new

      ...

   end
end

In this example, there's a variable being passed from the controller into the view: an array of select list options called @array_from_controller.

在本例中,有一个变量从控制器传递到视图:一个名为@array_from_controller的选择列表选项数组。


3) Route the http verb to your controller's method

Since I wanted a POSTed form to trigger the AJAX call, I routed the post verb for my controller to the render_partial_form view.

3)将http谓词路由到控制器的方法,因为我希望有一个已发布的表单来触发AJAX调用,所以我将控制器的post谓词路由到render_partial_form视图。

post 'someajax' => 'someajax#render_partial_form

The controller method defined by def render_partial_form matches with the name of the view, _render_partial_form.html.erb so there is no need to call a render action from the controller.

def render_partial_form定义的控制器方法与视图的名称_render_partial_form.html匹配。因此不需要从控制器调用呈现操作。


4) Create the partial view
The partial view should have the same name as your controller method and begin with an underscore: _render_partial_form.html.erb

4)创建部分视图部分视图应该与您的控制器方法具有相同的名称,并以下划线开头:_render_partial_form.html.erb

<h3>Here is the partial form</h3>

<%= form_tag("/next_step", method: 'post') do %>
    <%= label_tag(:data, "Some options: ") %>
    <%= select_tag(:data, options_for_select(@array_from_controller.transpose[0].collect)) %>
    <%= submit_tag('Next') %>
<% end %>


5) Create the JQuery file

5)创建JQuery文件

JQuery statements trigger the form's rendering. Replace "render_partial_form" with the actual name of your controller method and partial view. The slideDown effect is optional "eye candy". Create a file with a .js.erb extension, and the same name as your controller:

render_partial_form.js.erb

JQuery语句触发表单的呈现。用您的控制器方法和部分视图的实际名称替换“render_partial_form”。滑动效果是可选的“eye candy”。用.js创建一个文件。erb扩展名,与您的控制器同名:render_partial_form.js.erb

$('#render_partial_form').html("<%= escape_javascript (render partial: 'render_partial_form') %>");
$('#render_partial_form').slideDown(350);

#2


10  

You should use JS views (which have "js.erb" extension), something like "create.js.erb" for create controller action. Then, add format.js to the respond_to do |format| ... end block. And add remote: true parameter to your form. Notice: js.erb should include Javascript code you need to be included, like:

您应该使用JS视图(其中有“JS”)。erb扩展),类似于“create.js”。用于创建控制器动作。然后,添加格式。对respond_to do |格式|…块结束。并向窗体添加remote: true参数。注意:js。erb应该包含需要包含的Javascript代码,比如:

$("tbody#items").append("<%= j render(partial: 'your_partial_path') %>")

#3


2  

For what it's worth (because I was tripping up on this in an app upgrade from Rails 2 to 3): you can also do it by adding an event handler that appends the returned HTML, like the old Rails 2 prototype library used to do.

值得注意的是(因为我在从Rails 2升级到3的应用程序中遇到了这个问题):您还可以通过添加事件处理程序来附加返回的HTML,就像以前Rails 2原型库所做的那样。

If, for instance, you're trying to take this (prepare for a runon sentence):

举个例子,如果你想做这个(准备一个句子):

form_remote_tag url: {...}, update: ...

Where the response is coming in as HTML and being appended automatically, and replace it with this:

当响应以HTML形式输入并自动追加时,将其替换为:

form_tag {...}, remote: true

By adding an event handler to your application.js file that simply does the same thing, appending the content to a specific element, like this:

通过向应用程序添加一个事件处理程序。js文件只做同样的事情,将内容附加到一个特定的元素,如下所示:

$("#myform").on('ajax:success', function(e, data, status, xhr) {
  $("#container").append(data);
)};

Then... you may run into the same problem I did, which was that it never fires the ajax:success event! The problem is that it's expecting JS or text in the response, but it's getting HTML. The way to fix that is to tell it that the response will be HTML using an attribute on the form tag:

然后……您可能遇到了我做过的同样的问题,那就是它从不触发ajax:成功事件!问题是它期望在响应中有JS或文本,但它得到的是HTML。解决这个问题的方法是告诉它,响应将是HTML,使用表单标记上的属性:

form_tag {...}, remote: true, data: {type: :html}

Piece of cake!

块蛋糕!

#1


32  

Several things must be present for this to work, including the :remote => true flag on the triggering element, the respond_to :js flag in the controller's class definition, the route, the partial view, and lastly the jquery to actually render a dynamic partial must be contained in a separate .html.js file.

Examples below are for a fictitious "render_partial_form" method of the "someajax" controller.

要实现这一点,必须提供以下几样东西,包括:remote =>触发元素上的true标志、控制器类定义中的respond_to:js标志、路由、部分视图,以及实际呈现动态部分的jquery必须包含在一个单独的.html中。js文件。下面的例子是“someajax”控制器虚构的“render_partial_form”方法。


1) Add a :remote => true flag to the triggering element
put the :remote => true flag on the link or form tag in your .html.erb file (view) for the element that you want to trigger the AJAX call, like

1)在触发元素中添加:remote => true标志,将:remote => true flag放在链接上,或在.html中form标记。对于想要触发AJAX调用的元素,erb文件(视图)。

<%= form_tag("/someajax", method: 'post', :remote => true) do %>

with :remote => true, rails will not automatically switch views, which allows the JQuery to be run instead. This can be used with a form_tag, a link_tag, or other types of tags.

使用:remote =>确实,rails不会自动切换视图,这允许JQuery运行。这可以与form_tag、link_tag或其他类型的标记一起使用。


2) Add "respond_to :html, :js" at the top of the controller

At the top of your controller's class definition, you must now specify that the controller can respond to javascript as well as html:

2)在控制器类定义的顶部添加“respond_to:html,:js”,现在必须指定控制器既可以响应javascript,也可以响应html:

class SomeajaxController < ApplicationController
   respond_to :html, :js

   ...

   def render_partial_form
      @array_from_controller = Array.new

      ...

   end
end

In this example, there's a variable being passed from the controller into the view: an array of select list options called @array_from_controller.

在本例中,有一个变量从控制器传递到视图:一个名为@array_from_controller的选择列表选项数组。


3) Route the http verb to your controller's method

Since I wanted a POSTed form to trigger the AJAX call, I routed the post verb for my controller to the render_partial_form view.

3)将http谓词路由到控制器的方法,因为我希望有一个已发布的表单来触发AJAX调用,所以我将控制器的post谓词路由到render_partial_form视图。

post 'someajax' => 'someajax#render_partial_form

The controller method defined by def render_partial_form matches with the name of the view, _render_partial_form.html.erb so there is no need to call a render action from the controller.

def render_partial_form定义的控制器方法与视图的名称_render_partial_form.html匹配。因此不需要从控制器调用呈现操作。


4) Create the partial view
The partial view should have the same name as your controller method and begin with an underscore: _render_partial_form.html.erb

4)创建部分视图部分视图应该与您的控制器方法具有相同的名称,并以下划线开头:_render_partial_form.html.erb

<h3>Here is the partial form</h3>

<%= form_tag("/next_step", method: 'post') do %>
    <%= label_tag(:data, "Some options: ") %>
    <%= select_tag(:data, options_for_select(@array_from_controller.transpose[0].collect)) %>
    <%= submit_tag('Next') %>
<% end %>


5) Create the JQuery file

5)创建JQuery文件

JQuery statements trigger the form's rendering. Replace "render_partial_form" with the actual name of your controller method and partial view. The slideDown effect is optional "eye candy". Create a file with a .js.erb extension, and the same name as your controller:

render_partial_form.js.erb

JQuery语句触发表单的呈现。用您的控制器方法和部分视图的实际名称替换“render_partial_form”。滑动效果是可选的“eye candy”。用.js创建一个文件。erb扩展名,与您的控制器同名:render_partial_form.js.erb

$('#render_partial_form').html("<%= escape_javascript (render partial: 'render_partial_form') %>");
$('#render_partial_form').slideDown(350);

#2


10  

You should use JS views (which have "js.erb" extension), something like "create.js.erb" for create controller action. Then, add format.js to the respond_to do |format| ... end block. And add remote: true parameter to your form. Notice: js.erb should include Javascript code you need to be included, like:

您应该使用JS视图(其中有“JS”)。erb扩展),类似于“create.js”。用于创建控制器动作。然后,添加格式。对respond_to do |格式|…块结束。并向窗体添加remote: true参数。注意:js。erb应该包含需要包含的Javascript代码,比如:

$("tbody#items").append("<%= j render(partial: 'your_partial_path') %>")

#3


2  

For what it's worth (because I was tripping up on this in an app upgrade from Rails 2 to 3): you can also do it by adding an event handler that appends the returned HTML, like the old Rails 2 prototype library used to do.

值得注意的是(因为我在从Rails 2升级到3的应用程序中遇到了这个问题):您还可以通过添加事件处理程序来附加返回的HTML,就像以前Rails 2原型库所做的那样。

If, for instance, you're trying to take this (prepare for a runon sentence):

举个例子,如果你想做这个(准备一个句子):

form_remote_tag url: {...}, update: ...

Where the response is coming in as HTML and being appended automatically, and replace it with this:

当响应以HTML形式输入并自动追加时,将其替换为:

form_tag {...}, remote: true

By adding an event handler to your application.js file that simply does the same thing, appending the content to a specific element, like this:

通过向应用程序添加一个事件处理程序。js文件只做同样的事情,将内容附加到一个特定的元素,如下所示:

$("#myform").on('ajax:success', function(e, data, status, xhr) {
  $("#container").append(data);
)};

Then... you may run into the same problem I did, which was that it never fires the ajax:success event! The problem is that it's expecting JS or text in the response, but it's getting HTML. The way to fix that is to tell it that the response will be HTML using an attribute on the form tag:

然后……您可能遇到了我做过的同样的问题,那就是它从不触发ajax:成功事件!问题是它期望在响应中有JS或文本,但它得到的是HTML。解决这个问题的方法是告诉它,响应将是HTML,使用表单标记上的属性:

form_tag {...}, remote: true, data: {type: :html}

Piece of cake!

块蛋糕!