Rails中点击事件向ActionCable对应控制器传参的最佳方式
无表单传递固定参数实现方案
button_to本质是Rails自动生成了一个携带隐藏参数的表单、绑定提交事件,你要传递的是和用户输入无关的静态固定参数,完全不需要依赖表单或者链接标签做载体,直接给任意自定义元素绑定请求即可,样式完全不用被默认标签限制。
最灵活的原生JS实现
不用引入额外依赖,想给什么元素加点击交互就用什么元素,没有多余标签嵌套:
- 视图层直接写自定义按钮元素,把固定路径、参数存在
data-*属性上:
<!-- div、span、任意自定义标签都可以,完全按你的样式需求写 --> <div class="your-custom-btn-class" data-request-path="<%= MY_PATH %>" data-my-value="MY_VALUE"> <span>MY_TEXT</span> </div>
- 绑定点击事件发请求,记得带上Rails要求的CSRF令牌避免请求被拦截:
// 写在对应页面的JS脚本或者Stimulus控制器里均可 document.querySelectorAll('.your-custom-btn-class').forEach(btn => { btn.addEventListener('click', async () => { const requestPath = btn.dataset.requestPath const myValue = btn.dataset.myValue const csrfToken = document.querySelector('meta[name="csrf-token"]').content await fetch(requestPath, { method: 'PUT', headers: { 'X-CSRF-Token': csrfToken, 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ MY_KEY: myValue }) }) // 原有ActionCable广播、前端同步逻辑不需要改动,控制器收到请求后正常执行即可 }) })
零JS代码的Rails UJS方案
如果你的项目已经引入了@rails/ujs(Rails 6及之前版本默认自带,Rails 7配置importmap后也可使用),连点击事件都不用自己写,直接给元素加Rails UJS识别的data属性即可,效果和button_to完全一致,但不会生成多余的form嵌套:
<div class="your-custom-btn-class" data-url="<%= MY_PATH %>" data-method="put" data-remote="true" data-params="<%= { MY_KEY: 'MY_VALUE' }.to_param %>" > <span>MY_TEXT</span> </div>
注意:无论用哪种方案,前端传递的参数都需要在控制器端做必要的合法性校验,不要直接信任前端传入的任何值。
两种方案都不需要嵌套默认button标签、不需要重置浏览器自带的button默认样式,元素结构完全由你自己控制,比改造button_to生成的标签省事很多。
内容的提问来源于stack exchange,提问作者Clay Wightman
相关产品推荐
相关产品推荐

