如何用Hotwire实现选择切换账户时的整页重载并保留页面路径?
用Hotwire实现优雅的账户切换与页面重载
核心实现思路
利用Hotwire的Turbo进行页面导航,结合Stimulus控制器处理选择框的变化事件,既保留原需求的路径逻辑,又符合Hotwire的生态规范,避免内联JavaScript的冗余。
步骤1:编写选择框视图
直接使用select_tag(无需包裹在表单内,因为我们不需要提交表单,仅做导航),通过Stimulus的data-action绑定切换事件:
<%= select_tag :account_id, options_for_select( user.accounts.map { |account| [account.name, account.id] } + [['新建账户', 'new']], selected: current_account&.id ), prompt: "选择账户", data: { turbo: true, action: "change->account-switch#navigate" } %>
步骤2:创建Stimulus控制器
在app/javascript/controllers/account_switch_controller.js中编写逻辑,处理两种选择场景:
import { Controller } from "@hotwired/stimulus" export default class extends Controller { navigate(event) { const selectedValue = event.target.value // 处理「新建账户」跳转 if (selectedValue === 'new') { Turbo.visit('/accounts/new') return } // 处理现有账户切换:替换URL中的account_id并导航 const currentUrl = new URL(window.location.href) const pathSegments = currentUrl.pathname.split('/') const accountSegmentIndex = pathSegments.indexOf('accounts') + 1 // 如果当前页面在accounts嵌套路径下,替换account_id if (accountSegmentIndex < pathSegments.length) { pathSegments[accountSegmentIndex] = selectedValue currentUrl.pathname = pathSegments.join('/') Turbo.visit(currentUrl.toString()) } else { // 若当前不在accounts路径,跳转到该账户的默认页面(比如dashboard) Turbo.visit(`/accounts/${selectedValue}/dashboard`) } } }
关键说明
- 用Stimulus控制器替代内联
onchange,代码更易维护,符合Hotwire的组件化思想。 Turbo.visit会利用Hotwire的导航机制处理页面重载,相比直接修改location.href,能更好地利用Turbo的缓存、进度条等特性。- 增加了边界处理:当用户不在accounts嵌套页面时,自动跳转到该账户的默认页面,避免路径解析失败。
内容的提问来源于stack exchange,提问作者Michal Hájek
相关产品推荐
相关产品推荐

