3

我有一个相当标准的 Rails 5.2 应用程序(几乎遵循所有约定),使用 yarn 和 webpacker,1.1.1在我的package.jsonyarn.lock文件中有刺激版本。

# 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 Discourse 页面 ( https://discourse.stimulusjs.org/t/stimulusjs-and-turbolinks/669 ),从 Stimulus 开始1.1,刺激控制器在 DOM 准备好 turbolinks 后执行连接/初始化方法。

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

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

# 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()
    })
  }
}

HTML 表单:

<%= 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 %>

我在设置带有 turbolinks 的刺激控制器时遗漏了什么吗?

使用turbolinks:load事件处理程序,我可以获得我想要的功能,但从我在 Discourse 论坛上阅读的内容来看,我不应该使用事件处理程序。

我的应用程序是否有可能“缓存”了旧版本的刺激,即使package.json另有说明?

4

1 回答 1

3

据我了解,Stimulus 旨在与 Turbolinks 结合使用。如果您需要将代码包装在turbolinks:load. 您可能希望使用connect事件而不是initialize事件,因为在initialize首次实例化控制器时会触发事件。connect只要控制器连接到 DOM,就会触发该事件。

从生命周期回调的文档connection,它指出:

当以下两个条件都为真时,控制器连接到文档:

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

当控制器连接时,Stimulus 调用它的 connect() 方法。

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

# 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. 这篇文章是由发表了一些Stimulus 教程的人写的,所以他看起来相当有声望。我很难找到任何关于两者之间差异的详细信息,initialize除了connectinitialize触发一次并且connect每次附加到 DOM 时都会被触发。为了connect再次触发事件,需要disconnected在两者之间触发一个事件

于 2019-07-11T21:50:08.627 回答