如何在Ruby on Rails中用Stimulus切换布尔值并避免页面重载?
用Stimulus实现帖子标记无刷新切换
你当前通过表单提交实现标记功能会触发整页重载,完全可以用Stimulus改成无刷新版本,具体步骤如下:
原有代码参考
视图代码
<div class="form-check form-switch"> <%= form_with url: toggle_flag_post_path(@post), method: :patch, data: { turbo: false } do |f| %> <%= f.check_box :flag, { class: "form-check-input toggle-flag-checkbox", role: "switch", data: { post_id: @post.id }, onchange: "this.form.submit()" }, 1, 0 %> <%= f.label :flag, (@post.flag ? "Unflag" : "Flag"), class: "form-check-label" %> <% end %>
控制器方法
def toggle_flag @post.toggle!(:flag) redirect_back(fallback_location: @post) end
改造步骤
1. 创建Stimulus控制器
在app/javascript/controllers目录下新建toggle_flag_controller.js:
import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["checkbox", "label"] toggle() { const postId = this.checkboxTarget.dataset.postId const currentFlagState = this.checkboxTarget.checked fetch(`/posts/${postId}/toggle_flag`, { method: "PATCH", headers: { "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content, "Accept": "application/json" } }) .then(response => response.json()) .then(data => { this.checkboxTarget.checked = data.flag this.labelTarget.textContent = data.flag ? "Unflag" : "Flag" }) .catch(error => console.error('Error toggling flag:', error)) } }
2. 修改视图代码
移除表单结构,改用Stimulus绑定事件,无需触发表单提交:
<div class="form-check form-switch" data-controller="toggle-flag"> <%= check_box_tag :flag, 1, @post.flag, { class: "form-check-input", role: "switch", data: { post_id: @post.id, "toggle-flag-target": "checkbox", action: "toggle-flag#toggle" } } %> <%= label_tag :flag, (@post.flag ? "Unflag" : "Flag"), { class: "form-check-label", data: { "toggle-flag-target": "label" } } %> </div>
3. 调整后端控制器方法
让后端返回JSON格式的状态数据,而非重定向,供前端直接更新UI:
def toggle_flag @post.toggle!(:flag) render json: { flag: @post.flag } end
改造完成后,用户点击标记开关时,Stimulus会发送异步请求,后端返回最新标记状态,前端直接更新开关状态和标签文本,全程不会触发整页重载。
内容的提问来源于stack exchange,提问作者ANN17298
相关产品推荐
相关产品推荐

