使用AJAX和JQuery定时刷新Rails局部视图问题排查
问题分析与解决方案
你的核心问题在于JS模板没有正确生成替换DOM的逻辑,以及后续修改时的语法错误导致更新失效。咱们一步步梳理修复:
1. 修正JS模板的语法错误
你修改后的single_live.js.slim(注意文件名要保持和控制器响应一致,是single_live.js.slim而非single_live_js.slim)写法存在语法问题,正确的姿势是用escape_javascript(简写j)转义partial的HTML内容,生成有效的JS代码来替换目标元素:
| $("#captured_vehicles_live").html("#{j render partial: 'captured_vehicles_live', locals: { all_captured_violators: @all_captured_violators }}");
这里两个关键细节:
- 用
locals把控制器里的@all_captured_violators传递给partial,避免依赖全局实例变量,代码更规范健壮 j方法会自动转义HTML里的引号、换行等特殊字符,防止JS语法报错
2. 简化前端JS逻辑
既然JS模板已经包含了DOM替换的逻辑,前端的refreshPartial函数只需要发起请求即可,不需要额外处理回调:
// application.js $(document).ready(function () { // 注意:你原来写的是1000毫秒(1秒),如果要每10秒刷新改成10000哦 setInterval(refreshPartial, 10000); }); function refreshPartial() { $.get("/single_live.js"); }
3. 确保控制器查询不被缓存
Rails默认会缓存数据库查询结果,这会导致新增数据无法实时获取,你可以在控制器里强制禁用查询缓存:
# static_pages_controller.rb def single_live # 禁用查询缓存,确保每次请求都拉取最新数据 ActiveRecord::Base.uncached do @all_captured_violators = CapturedViolatorPlaceholder.all.order('capture_date DESC') end respond_to do |format| format.html format.js end end
4. 兼容partial的变量接收
为了让partial既能通过实例变量也能通过局部变量接收数据,建议在partial开头做兼容处理:
# _captured_vehicles_live.html.slim - all_captured_violators ||= @all_captured_violators # 兼容两种变量传递方式 #captured_vehicles_live.ui.segment style="height: 450px; margin-top: 15px; overflow:scroll;" .ui.grid.stackable - all_captured_violators.each do |violator| .row.ui.basic.segment # 你的原有内容...
为什么原来的方案失效?
- 最初的
single_live.js.slim只是渲染了partial的HTML,但没有生成任何JS代码来把HTML插入到页面中,前端拿到HTML后用html(data)替换看似能工作,但实际因为查询缓存导致数据没有更新 - 你修改后的JS模板语法错误,字符串拼接不规范,导致生成的JS代码无效,无法执行DOM替换
内容的提问来源于stack exchange,提问作者Whooper
相关产品推荐
相关产品推荐

