0

使用 Haml,ruby 2.7.2,rails 6.1.2.1,刺激 ^2.0.0

所以,我使用了一个显示选择类型的嵌套表单。根据选择类型的值,我将显示或隐藏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 并给它选择对象以立即工作,但我不确定如何在 html/ script标签中执行此操作。谢谢你的帮助!

这是我的相关代码,应该有所帮助: _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,如下所示:

  1. 我添加一个问题
  2. 我从select标记中选择一个选项,该选项会触发 select → change 事件:nested-form#update_q_type
  3. 如果我选择OptionCheckbox,那么我会显示div,否则我会隐藏div

在此处输入图像描述

现在,这就是我尝试触发 select → change 事件的原因。如果我再次开始编辑此记录,它会很好地加载数据。但是,它不知道何时显示答案div。这就是为什么我需要触发 select → change 事件,以便它可以正确设置答案div以隐藏或显示。否则,它默认始终“隐藏”。

我在下面还有另一个 .gif。如您所见,它加载了选择选项的选择。如果我再次尝试选择选项,它不会做任何事情......因为它并没有真正改变。如果我将其更改为Checkbox,它当然会更新。所以基本上,我需要做这个onLoad,你可以说。

在此处输入图像描述

也许有不同的方法可以做到这一点?谢谢您的帮助!

更新:我没有意识到我的 html 标签被解释为 html。哎呀。将所有标签更改为斜体字。例如: '/</select/>/' 现在只是select。我还扩展了该问题以进行更多说明。

4

1 回答 1

0

StimulusJS 有一个初始化函数,它基本上在页面加载时运行。你会用它来达到这个目的。这里唯一的另一个问题是您将一个事件传递给update_q_type并且您不会在initialize. 所以我发现的工作是将大部分代码提取到一个单独的函数中,我的初始化和点击函数都可以调用。这可以帮助您保持代码干燥。

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方法。它意味着非常模块化。

于 2021-03-03T15:44:36.537 回答