You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:21:04