在JS模块中使用Rails-UJS(带有webpacker的Rails 6)

R4t*_*ake 14 ruby-on-rails webpack webpacker rails-ujs

我刚刚切换到Rails 6(6.0.0.rc1),它默认将Webpacker gem用于Javascript资产以及Rails-UJS。我想在某些模块中使用Rails UJS,以便通过以下功能提交表单:

const form = document.querySelector("form")
Rails.fire(form, "submit")
Run Code Online (Sandbox Code Playgroud)

在安装了Webpacker的以前的Rails版本中,该Rails引用似乎在我的模块中“全局”可用,但是现在我在调用Rails.fire… 时得到此引用

ReferenceError: Rails is not defined
Run Code Online (Sandbox Code Playgroud)

我怎样才能让Rails@rails/ujs提供给特定的或我所有的模块?

在我的设置下面...

app / javascript / controllers / form_controller.js

import { Controller } from "stimulus"

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

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))
Run Code Online (Sandbox Code Playgroud)

app / javascript / packs / application.js

require("@rails/ujs").start()
import "controllers"
Run Code Online (Sandbox Code Playgroud)

谢谢!

Thi*_*uBS 18

首先,使用yarn add rails/ujs:

yarn add  @rails/ujs
Run Code Online (Sandbox Code Playgroud)

并添加到 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
Run Code Online (Sandbox Code Playgroud)

配置和加载 Rails js。

# pack/application.js
require("@rails/ujs").start()
global.Rails = Rails;
Run Code Online (Sandbox Code Playgroud)

然后:这是结果-> 我在 Firefox 控制台中输入 Rails 时的结果


ino*_*tus 8

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

import Rails from '@rails/ujs';
Rails.start();
Run Code Online (Sandbox Code Playgroud)

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

import Rails from '@rails/ujs';
Run Code Online (Sandbox Code Playgroud)

  • 没有缺点 - 事实上,我想说这正是我们在模块化 ES6 世界中声明每个文件的依赖关系的方式。Webpack 只会加载 `@rails/ujs` 一次,无论导入多少次。每个控制器都简单地获得相同的“Rails”导出,即使您使用不同的名称导入它,或者使用 CommonJS“require()”而不是 ES6“import”,情况仍然如此。请注意只调用一次“.start()”,可能是在“application.js”中。 (4认同)
  • @Dan L:依赖全局变量是最臭名昭著的编程反模式之一,所以不,我不认可 ProvidePlugin,而是专门认可导入依赖项。编写依赖于全局运行时状态的模块是人们最终陷入这种混乱的原因。考虑到问题是关于_编写模块_,更是如此。依赖于全局状态的模块不是......模块化的。 (4认同)

And*_*nic 5

只需将其添加到您的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']
    })
)
Run Code Online (Sandbox Code Playgroud)

  • 请参阅它以获取 JavaScript 中的 Rails 实例。/sf/answers/4071304051/ (2认同)