具有Turbolinks的StimulusJS,必须等待“ turbolinks:load”事件才能执行StimulusJS控制器

时间:2019-07-09 22:00:54

标签: ruby-on-rails ruby-on-rails-5 turbolinks stimulusjs

我有一个使用纱线和Webpacker的相当标准的Rails 5.2应用程序(几乎遵循所有约定),并且在我的IASTName1.1.1文件中有刺激版本package.json

yarn.lock

从Stimulus # package.json { "name": "MY_APP_NAME", "private": true, "dependencies": { "@rails/webpacker": "^4.0.2", "coffeescript": "1.12.7", "stimulus": "^1.1.1" }, "devDependencies": { "webpack-dev-server": "^3.2.1" } } 开始的StimulusJS论述页面(https://discourse.stimulusjs.org/t/stimulusjs-and-turbolinks/669)中,在DOM准备好turbolinks之后,刺激控制器执行连接/初始化方法。

但是,我可以让下面的控制器正确执行的唯一方法是添加事件处理程序,以等待1.1事件被触发。

如果有相关信息,我正在尝试使用jQuery Select2插件来创建自定义选择元素。

turbolinks:load

HTML表单:

# app/javascript/packs/controllers/intake_customization_controller.js
import { Controller } from "stimulus";

export default class extends Controller {
  static targets = [ "userIds" ]

  initialize() {
    // Code will not execute without this event handler wrapping it...
    $(document).on("turbolinks:load", ()=> {
      $(this.userIdsTarget).select2()
    })
  }
}

我是否缺少通过Turbolink设置刺激控制器的东西?

使用<%= form_with model: @account, url: settings_intake_customization_path, method: :put, id: "settings-intake_customization-form", data: { controller: "intake-customization" } do |form| %> <%= form.collection_select :user_ids, current_account.users, :id, :name, { include_blank: false }, { multiple: true, data: { target: "intake-customization.userIds" } } %> <% end %> 事件处理程序,我可以获得所需的功能,但是从Discourse论坛上阅读的内容中,我不必使用事件处理程序。

即使turbolinks:load另有说明,我的应用是否有可能“缓存”了较早版本的Stimulus?

1 个答案:

答案 0 :(得分:0)

据我了解,Stimulus旨在与Turbolinks协同工作。如果您需要将代码包装在turbolinks:load的事件处理程序中,我会感到惊讶。您可能希望使用connect事件而不是initialize事件,因为在首次实例化控制器时会触发initialize事件。只要控制器连接到DOM,就会触发connect事件。

connection生命周期回调的docs中,它指出:

  

满足以下两个条件时,将控制器连接到文档:

     
      
  • 其元素存在于文档中(即document.documentElement的后代,即元素)
  •   
  • 其标识符显示在元素的data-controller属性中
  •   
     

连接控制器后,Stimulus会调用其connect()方法。

由于您要使用jQuery Select2操作DOM,因此connect生命周期回调对我来说似乎更合适。我将做更多研究,但我可以想象每次在控制器的代码加载到浏览器中时都会触发initialize事件。如果是这种情况,则很可能在使用您的控制器(以及您要查询的DOM元素)的DOM树的一部分有机会呈现之前initialize事件被触发:

# app/javascript/packs/controllers/intake_customization_controller.js

import { Controller } from "stimulus";

export default class extends Controller {
  static targets = [ "userIds" ]

  connect() {
    $(this.userIdsTarget).select2()
  }
}

我能够找到一个说connect而不是turbolinks:load的{​​{3}}。本文由发表过少量article的人撰写,因此他似乎颇有声誉。除了initialize被触发一次和每次connect被触发之外,我很难找到关于initializeconnect之间差异的详细信息DOM。为了再次触发connect事件,需要在两者之间触发disconnected事件