如何通过在Rails上启用Turbolinks的AJAX正确呈现部分?
我目前正在开发一个Rails应用程序,它必须与外部Web API通信,从结果更新DB记录并异步更新视图。
我目前在做什么
我有一个list
操作,我直接从数据库中显示数据,其中包含一个在分页表中发送的电子邮件列表。 呈现视图后,我需要向应用程序(在不同的路径上)发出一个AJAX请求,该请求向外部Web API发出请求,更新数据库,然后使用包含所有电子邮件的table
呈现部分,同样在原始list
操作上呈现的。
以下代码处理AJAX请求:
# _mail_list_loader.js.erb document.addEventListener("turbolinks:load", function() { $.ajax({ url: '/certified_mail/mail_list', type: 'get', data: { page: , rut: , from: , to: , ids: } }); });
哪个响应是.js.erb
呈现实际table
的部分:
# mail_list.js.erb $('#mail-list').html('');
_mail_list_loader.js.erb
在我的application.html.erb
呈现:
# application.html.erb ...
对于首先加载表的操作和处理AJAX请求的操作,我的控制器看起来像这样:
class CertifiedMailController < ApplicationController def list if params[:page].nil? || params[:page].to_i <= 0 redirect_to action: :list, params: { page: 1, from: params[:from].to_s.empty? ? nil : params[:from], to: params[:to].to_s.empty? ? nil : params[:to] } else # Handle filters and get emails from the DB end end def mail_list if request.xhr? # Make API request, update accordingly, # handle filters and get emails from the DB respond_to do |format| format.js end else redirect_to action: :list end end end
我的问题是什么
当页面首次加载时,它从控制器加载,并且AJAX请求被正确发送,但是如果我转到下一页(它发送带有不同GET参数page
的请求),页面直接从控制器加载,但是发送两个AJAX请求,一个用于第一页,一个用于第二页,如下所示, table
的HTML有点随机更改,而不是真正显示table
的正确数据:
我以前使用JavaScript来使AJAX请求在body
定义,而不是header
但是这样的请求只会在每次页面更改时保持重复,每次都会有越来越多的请求。 我做了一些搜索,发现通过将代码移到head
可以解决额外调用的问题。
我真的不知道我的问题是否与Turbolinks如何处理请求完全相关,但我需要的是应用程序呈现完整视图然后将具有完全相同的GET
参数的AJAX请求发送到另一个不同的操作使用表格呈现部分。
任何帮助将非常感谢!
因为您在_mail_list_loader.js.erb
有动态内容, _mail_list_loader.js.erb
您可能会注意到中的脚本标记在后续页面加载时被复制。 尽管它被编写为一个代码块,但Turbolinks并没有“看到”它,而是在每个负载上附加一个新的脚本元素。
我建议您尝试将尽可能多的JavaScript移动到.js
文件中,并将它们包含在应用程序清单中。 您可以通过将它们作为属性呈现来获取动态服务器生成的变量,并让JS选择它们。
例如,您可能想要尝试以下内容:
# app/views/certified_mail/list.html.erb <% props = { page: @page, rut: @rut, from: @from, to: @to, ids: @outdated_message_ids } %> …
# app/assets/javascripts/load_mail_list.js ;(function () { function loadMailList (data, callback) { $.ajax({ url: '/certified_mail/mail_list', type: 'get', dataType: 'html', data: data, success: callback }) } $(document).on('turbolinks:load', function () { var $element = $('[data-component=mail-list]') loadMailList($element.data('props'), function (html) { $element.html(html) }) }) })()
# app/controllers/certified_mail_controller.rb def mail_list if request.xhr? # Make API request, update accordingly, # handle filters and get emails from the DB render 'certified_mail/mail_list' else redirect_to action: :list end end
回调应确保响应将列表呈现为正确的元素(而在此之前,如果某人快速分页,则可能存在第3页上呈现第2页列表的风险)。
希望有所帮助。
从我在这个答案中看到的,在某些链接上禁用Turbolinks正是我需要完全重新加载我的JavaScript所以我去了分页链接发送请求更改参数(例如page
)并简单地添加'data-turbolinks': false
对它'data-turbolinks': false
。
现在没有额外的AJAX调用,因为链接现在只渲染整个HTML,而不是通过Turbolinks。
- Ruby on Rails:路由问题:在link_to中没有看到动作
- RailsTutorial 3.2 Ch 9 – “before {valid_signin(user)}”导致RSpec测试失败
- Rails 3:如何进行Ajax调用?
- Rails跨域ajax获取请求(CORS)
- 将Ajax POST请求的参数格式化为Rails控制器 – 用于jQuery-UI可排序列表
- Rails 3:未定义的方法`remote_form_for’
- Ruby on rails:如何从登录弹出窗口向用户提供的凭据发送一个AJAX请求到rails控制器
- ajax:success和ajax:在Rails中使用UJS时,完全回调不起作用
- Rails ajax:成功回调不会在生产中触发
- 如果没有在Rails 3中重新加载,数据库值不会出现在同一页面中
- 如何将remote_form_for的:update =>’div_id’选项从Rails 2升级到Rails 3?