问题描述
使用 Haml,ruby 2.7.2,rails 6.1.2.1,stimulation ^2.0.0
因此,我使用的是显示 select 类型的嵌套表单。根据 select 类型的值,我将显示或隐藏 div。我正在将我的咖啡脚本转换为刺激,但我不确定如何强制触发更改事件,或者只是运行检查 select 值的代码来决定是否应该隐藏或显示 div。过去,在我的 html.haml 视图中,我会称之为:
:javascript
$('select.answer_type').change()
基于此处的另一篇文章:https://discuss.hotwire.dev/t/triggering-turbo-frame-with-js/1622,我尝试将其更改为:
:javascript
q_typeTarget.dispatchEvent(new Event('change'));
那没有用。也许有另一种方法可以做到这一点,或者我使用错误的词汇来查找我想要做的例子?我宁愿手动执行 Controller#action 并给它 select 对象以立即处理,但我不确定如何在 html/script 中执行此操作em> 标签。感谢您的帮助!
这是我的相关代码,应该会有所帮助:
_question_fields.html.haml
.nested-fields.question
.form_group.grid-x
.fields.cell.shrink
= f.select :answer_type,options_for_select(["String","Option","CheckBox"],f.object.answer_type),{},class: 'answer_type',data: {nested_form_target: 'q_type',action: 'nested-form#update_q_type'}
.cell.answers_group{ style: 'visibility: hidden; display: none'}
= render partial: 'answers',locals: { f: f,q_level: q_level }
:javascript
q_typeTarget.dispatchEvent(new Event('change'));
nested_form_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
static targets = ["q_type","answers"]
update_q_type(event) {
event.preventDefault()
console.log('You have selected ' + this.q_type )
let d_question = event.target.closest(".question")
let d_select = d_question.querySelector("select")
let d_answer = d_question.querySelector(".answers_group")
console.log('Select: ' + d_select.value )
switch(d_select.value) {
case 'Option':
case 'CheckBox':
console.log(' Show Answers ')
d_answer.style.visibility = "visible"
d_answer.style.display = null
return
default:
console.log(' Hide Answers ')
d_answer.style.visibility = 'hidden'
d_answer.style.display = 'none'
return
}
}
这是嵌套表单的示例 .gif,如下所示:
- 我添加了一个问题
- 我从 select 标签中选择了一个 option,它会触发 select → change 事件:
nested-form#update_q_type
- 如果我选择选项或复选框,则显示div,否则隐藏div
现在,这就是我尝试触发 select → change 事件的原因。如果我再次开始编辑这条记录,它加载数据就好了。但是,它不知道何时显示答案div。这就是为什么我需要触发 select → change 事件,以便它可以正确设置答案 div 以隐藏或显示。否则,它默认为总是“隐藏”。
我在下面还有另一个 .gif。如您所见,它加载了选择了 Option 的选择。如果我再次尝试选择 Option,它不会做任何事情...因为它并没有真正改变。如果我将其更改为 CheckBox,它当然会更新。所以基本上,我需要在 onLoad 上做这个,你可以说。
也许有不同的方法来做到这一点?感谢您的帮助!
更新: 我没有意识到我的 html 标签被解释为 html。哎呀。将所有标签更改为斜体字。例如:'//>/' 现在只是 select。此外,我还对问题进行了详细说明以进行更多说明。
解决方法
StimulusJS 有一个初始化函数,它基本上在页面加载时运行。您将为此目的使用它。这里唯一的另一个问题是,您将事件传递给 update_q_type
,而 initialize
上没有事件。所以我发现有效的是将大部分代码提取到一个单独的函数中,我的 initialize 和 click 函数都可以调用。这有助于您保持代码干燥。
export default class extends Controller {
static targets = ["q_type","answers"]
initialize() {
this.switch(this.q_typeTarget)
}
update_q_type(event) {
event.preventDefault
this.switch(this.q_typeTarget)
}
switch(q_type) {
...
}
}
需要注意的一点是,不清楚您是在此处运行一个刺激控制器还是每个选择框组合都运行一个。您可以执行第二个操作,而不必使用 closest
方法。这意味着非常模块化。