Rails 4 使用 ajax、jquery、:remote => true 和 respond_to 渲染部分

Posted

技术标签:

【中文标题】Rails 4 使用 ajax、jquery、:remote => true 和 respond_to 渲染部分【英文标题】:Rails 4 rendering a partial with ajax, jquery, :remote => true, and respond_to 【发布时间】:2015-01-04 16:25:57 【问题描述】:

使用 AJAX 动态呈现页面以响应提交的表单似乎很常见。其他类似的问题都没有集中在如何以一般方式执行此操作。

我能找到的关于这个主题的最好的博客文章在这里:http://www.gotealeaf.com/blog/the-detailed-guide-on-how-ajax-works-with-ruby-on-rails

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

【问题讨论】:

【参考方案1】:

必须存在一些东西才能使其工作,包括触发元素上的 :remote => true 标志、控制器类定义中的 respond_to :js 标志、路由、部分视图,最后是实际的 jquery渲染动态部分必须包含在单独的 .html.js 文件中。以下示例针对“someajax”控制器的虚构“render_partial_form”方法。

1) 向触发元素添加 :remote => true 标志 将 :remote => true 标志放在 .html.erb 文件(视图)中的链接或表单标记上,以获取要触发 AJAX 调用的元素,例如

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

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

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

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

3) 将 http 动词路由到控制器的方法 因为我想要一个 POSTed 表单来触发 AJAX 调用,所以我将控制器的 post 动词路由到 render_partial_form 视图。

post 'someajax' => 'someajax#render_partial_form

def render_partial_form 定义的控制器方法与视图名称 _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) 创建 JQuery 文件

JQuery 语句触发表单的呈现。将“render_partial_form”替换为控制器方法和局部视图的实际名称。 slideDown 效果是可选的“眼睛糖果”。 创建一个扩展名为 .js.erb 的文件,并与您的控制器同名: render_partial_form.js.erb

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

【讨论】:

在较新的 Rails 版本中,您将需要 'responders' gem 来实现控制器级 respond_to :html, :js partial 需要与 AJAX 方法命名相同的事实拯救了我。我希望其他人能够找到这个,很好的答案。 谢谢。实际上,我最近在另一个项目上让它工作时遇到了一些麻烦......我想知道 data: type: :html 是否需要在 form_tag 上,根据 mltsy 的回答。【参考方案2】:

您应该使用 JS 视图(具有“js.erb”扩展名),例如“create.js.erb”来创建控制器操作。然后,将format.js 添加到respond_to do |format| ... end 块中。并将 remote: true 参数添加到您的表单中。 注意:js.erb 应该包含你需要包含的 Javascript 代码,比如:

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

【讨论】:

【参考方案3】:

对于它的价值(因为我在从 Rails 2 升级到 3 的应用程序中遇到了这个问题):你也可以通过添加一个附加返回的 HTML 的事件处理程序来做到这一点,就像使用的旧 Rails 2 原型库一样去做。

如果,例如,你试图接受这个(准备一个连续的句子):

form_remote_tag url: ..., update: ...

响应以 HTML 格式输入并自动附加,并将其替换为:

form_tag ..., remote: true

通过将事件处理程序添加到您的 application.js 文件中,它只是做同样的事情,将内容附加到特定元素,如下所示:

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

那么...你可能会遇到和我一样的问题,那就是它永远不会触发ajax:success 事件!问题是它在响应中期待 JS 或文本,但它正在获取 HTML。解决这个问题的方法是使用表单标签上的属性告诉它响应将是 HTML:

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

小菜一碟!

【讨论】:

以上是关于Rails 4 使用 ajax、jquery、:remote => true 和 respond_to 渲染部分的主要内容,如果未能解决你的问题,请参考以下文章

ajaxSetup 不适用于 Rails / jquery-ujs

AJAX 日历更新页面 rails 4

Ruby on Rails 6. 使用带有 Ajax 的 Bootstrap 4 工具提示

是否将使用jquery ajax/Rails分页

jQuery 表单插件 + Ajax 文件上传 + Rails

如何使用 rails 和 jquery 优化 ajax 搜索