使用Hotwire/Stimulus时无法引用JavaScript控制器中的函数
问题:Stimulus控制器方法未定义错误
我不确定这是本地配置问题还是代码问题,在现有控制器上新增函数后调用失败,提示引用了未定义的方法。已经在布局中指定控制器,视图里也做了引用,但还是报错:

我执行的启动步骤:
$ rm -rf public/assets $ rails assets:precompile $ bundle install $ rails s
相关代码
布局文件 application.html.erb
<body data-controller="modal data"> <%= yield %> </body>
Stimulus控制器 modal_controller.js
import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["container", "background", "panel", "terms"] changeVisibility(element, visible) { console.log(element, hidden); if (visible) { $(element).on('click', function () { $('#terms_modal').removeClass('hidden'); }); } else { $(element).on('click', function () { $('#terms_modal').addClass('hidden'); }); } }; }
视图文件 app/views/home/girl.html.erb
<p>您同意我们的 <a class="text-red open_terms" data-action="click->modal#changeVisibility('terms_modal', true)">服务条款</a></p>
控制器注册文件 app/javascript/controllers/index.js
// This file is auto-generated by ./bin/rails stimulus:manifest:update // Run that command whenever you add a new controller or create them with // ./bin/rails generate stimulus controllerName import { application } from "./application" // other controllers import ModalController from "./modal_controller" application.register("modal", ModalController)
编辑补充
已确认控制器成功注册并加载,新增的connect方法能正常打印日志:
connect() { console.log("connected"); };
文件也处于监听状态,修改后能生效:

解决方案
1. 修正Stimulus动作传参格式
Stimulus的动作传参不能直接写('terms_modal', true),需要用方括号包裹参数,字符串参数加引号,正确格式:
<p>您同意我们的 <a class="text-red open_terms" data-action="click->modal#changeVisibility" data-modal-change-visibility-param='["terms_modal", true]'>服务条款</a></p>
也可以拆分参数用data-*传递:
<a class="text-red open_terms" data-action="click->modal#changeVisibility" data-modal-target-id-value="terms_modal" data-modal-visible-value="true"> 服务条款 </a>
2. 修正控制器方法的参数接收逻辑
Stimulus动作方法的第一个参数是事件对象,自定义参数需通过event.params获取,同时修复重复绑定点击事件的问题:
changeVisibility(event) { const [elementId, visible] = event.params; const $element = $(`#${elementId}`); // 修复原代码中未定义的`hidden`变量 visible ? $element.removeClass('hidden') : $element.addClass('hidden'); }
3. 修正布局中的控制器声明
data-controller="modal data"里的空格会被解析为两个控制器(modal和data),若没有data控制器会引发额外错误,改成:
<body data-controller="modal"> <%= yield %> </body>
4. 修复控制器中的未定义变量
原代码里console.log(element, hidden);的hidden变量未定义,需替换为实际可用变量(比如!visible)。
内容的提问来源于stack exchange,提问作者mirando
相关产品推荐
相关产品推荐

