在 JS 模块中使用 Rails-UJS (Rails 6 with webpacker)

Using Rails-UJS in JS modules (Rails 6 with webpacker)

我刚切换到 Rails 6 (6.0.0.rc1),它默认使用 Webpacker gem Javascript 资产以及 Rails-UJS。我想在我的一些模块中使用 Rails UJS,以便从具有以下功能的函数提交表单:

const form = document.querySelector("form")
Rails.fire(form, "submit")

在安装了 Webpacker 的前 Rails 版本中,Rails 引用似乎在我的模块中 "globally" 可用,但现在我在调用 Rails.fire 时得到了这个……

ReferenceError: Rails is not defined

如何使 @rails/ujs 中的 Rails 可用于我的特定或所有模块?

低于我的设置…

app/javascript/controllers/form_controller.js

import { Controller } from "stimulus"

export default class extends Controller {
  // ...
  submit() {
    const form = this.element
    Rails.fire(form, "submit")
  }
  // ...
}

app/javascript/controllers.js

// Load all the controllers within this directory and all subdirectories. 
// Controller files must be named *_controller.js.

import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"

const application = Application.start()
const context = require.context("controllers", true, /_controller\.js$/)
application.load(definitionsFromContext(context))

app/javascript/packs/application.js

require("@rails/ujs").start()
import "controllers"

谢谢!

只需将它添加到您的 environment.js 文件,这是我的(bootstrap 和 jquery):

const {environment} = require('@rails/webpacker')
const webpack = require('webpack')

module.exports = environment

environment.plugins.prepend(
    'Provide',
    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        jquery: 'jquery',
        'window.jQuery': 'jquery',
        "window.$": "jquery",
        Popper: ['popper.js', 'default'],
        Rails: ['@rails/ujs']
    })
)

我目前正在研究 6.0.0.rc2,但我想我已经找到了答案。

因此,如果您分离出:

app/javascript/packs/application.js

require("@rails/ujs").start()
import "controllers"

改为:

export const rails_ujs = require("@rails/ujs")
console.log(rails_ujs)
rails_ujs.start()

你显然可以删除 console.log 只是想弄清楚事情。 然后在你的刺激控制器中你可以简单地做:

// Visit The Stimulus Handbook for more details
// https://stimulusjs.org/handbook/introduction
//
// This example controller works with specially annotated HTML like:
//
// <div data-controller="hello">
//   <h1 data-target="hello.output"></h1>
// </div>

import { Controller } from "stimulus"
import { rails_ujs } from "packs/application.js"

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

  connect() {
    // this.outputTarget.textContent = 'Hello, Stimulus!'
    console.log('hi')
    console.log(rails_ujs)
  }
}

只是在这里使用他们的小测试控制器,但我把它 console.log 出来了,你可以调用 rails_ujs.fire 所以这应该是你想要的:)

让我知道这是否适合您!

在我的 app/javascript/packs/application.js:

import Rails from '@rails/ujs';
Rails.start();

然后在我写的任何模块、控制器、组件中:

import Rails from '@rails/ujs';

我认为最好的方法是使用 expose-loader 并像 webpacker 一样配置它 运行 bundle exec rails webpacker:install:erb.


安装 expose-loader

$ yarn add expose-loader

创建配置文件

  1. 对于加载器,webpacker 会自行配置,它会在 config/webpack/loaders 中转储一个配置对象。如果该文件夹不存在,请创建该文件夹。

  2. 创建一个名为 config/webpack/loaders/expose.js

    的文件
  3. 将此添加到该文件:

    module.exports = {
      test: require.resolve('@rails/ujs'),
      use: [{
        loader: 'expose-loader',
        options: 'Rails'
       }]
    }
    
    // later versions of expose loader may allow the following API:
    module.exports = {
      test: require.resolve('@rails/ujs'),
      loader: 'expose-loader',
      options: {exposes: "Rails"}
    }
    

将该加载程序添加到 environment.js

将这两行添加到 config/webpack/environment.js:

const expose = require('./loaders/expose')
environment.loaders.prepend('expose', expose)

完整文件应如下所示:

const { environment } = require('@rails/webpacker')
const expose = require('./loaders/expose')

environment.loaders.prepend('expose', expose)
module.exports = environment

这应该能让您再次全局访问 Rails 对象。

首先,使用 yarn add rails/ujs:

yarn add  @rails/ujs

并添加到config/webpack/environment.js

const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default'],
    toastr: 'toastr/toastr',
    ApexCharts: ['apexcharts', 'default'],
    underscore: ['underscore', 'm'],
    Rails: ['@rails/ujs']
  })
)
module.exports = environment

配置并加载Rails js。

# pack/application.js
require("@rails/ujs").start()
global.Rails = Rails;

然后: 这是结果->