Ruby on Rails如何实现点击按钮后在其他页面展示指定数据
问题核心原因
你当前的写法混淆了Ruby on Rails的服务端渲染逻辑和前端浏览器执行逻辑:
<%= %>是ERB模板语法,只会在服务器端生成页面的时候执行,页面发送到用户浏览器之后,所有ERB代码都已经被转换成了纯HTML/文本,浏览器无法识别、执行ERB代码- 直接在
onclick里写前端JS跳转到独立页面是可行的,但不符合Rails的开发惯例,维护成本更高,优先用Rails原生的路由+控制器+视图流实现。
推荐实现方案(Rails惯例写法)
不需要写自定义的myFunction前端方法,按以下4步调整即可:
- 添加路由
在config/routes.rb中新增独立页面的路由规则:
# config/routes.rb get '/pods/detail', to: 'pods#detail', as: :pod_detail
- 添加控制器动作
在对应管理Pod的控制器中新增动作,负责查询要展示的数据:
# app/controllers/pods_controller.rb def detail # 替换成你实际查询Pod对象的逻辑,比如根据传入的pod_id查询 @pod = Pod.find(params[:pod_id]) @index = params[:index].to_i # Rails会自动渲染 app/views/pods/detail.html.erb 模板 end
- 编写独立展示页视图
新建app/views/pods/detail.html.erb文件,放入你要展示的表格内容:
<!-- app/views/pods/detail.html.erb --> <table class="table"> <thead> <tr> <th>序号</th> <th>Pod名称</th> <th>创建时间</th> </tr> </thead> <tbody> <tr> <td><%= @index %></td> <td><%= @pod.metadata.name %></td> <td><%= @pod.metadata.creationTimestamp %></td> </tr> </tbody> </table>
- 替换原有按钮代码
把你原来绑定onclick的按钮替换为Rails自带的button_to辅助方法,自动处理跳转、参数传递和CSRF校验:
<%# 注意:index的自增不要写在按钮内部,否则渲染页面时就会触发自增,导致序号错乱,列表渲染时提前算好当前条目的index值即可 %> <%= button_to "查看Pod详情", pod_detail_path(pod_id: pod.id, index: current_index), class: "alert alert-primary", style: "margin:10px;", method: :get %>
备选方案(纯JS跳转实现)
如果你一定要保留myFunction的写法,注意必须在ERB渲染阶段就把需要的参数值注入到JS调用里,不要试图在JS里直接写ERB代码:
<script> function myFunction(podName, createTime, index) { // 跳转到对应独立页面 window.location.href = `/pods/detail?pod_name=${encodeURIComponent(podName)}&create_time=${encodeURIComponent(createTime)}&index=${index}` } </script> <!-- 按钮处传入提前渲染好的参数值 --> <button class="alert alert-primary" style="margin:10px;" onclick="myFunction('<%= j pod.metadata.name %>', '<%= j pod.metadata.creationTimestamp %>', '<%= current_index %>')"> 查看Pod详情 </button>
注意:这种写法需要额外处理参数转义、特殊字符编码问题,安全性和可维护性都不如上面的原生Rails方案,非必要不使用。
注意事项
- 不要给按钮加
role="alert"属性,alert是无障碍访问中用于提示信息的角色,用在按钮上会导致屏幕阅读器识别错误 - 所有数据查询逻辑放在服务端控制器实现,不要把全量数据提前塞到前端DOM中再通过JS传递,避免数据泄露和转义问题
- ERB的代码执行时机早于前端JS,不要指望在用户点击按钮时才触发
<%= index +=1 %>这类Ruby逻辑,这类代码在页面加载完成时就已经执行完毕了
内容的提问来源于stack exchange,提问作者Nanda Pandian
相关产品推荐
相关产品推荐

