37

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

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

在安装了 Webpacker 的以前的 Rails 版本中,Rails引用似乎在我的模块中“全局”可用,但现在我在调用时得到了这个Rails.fire……</p>

ReferenceError: Rails is not defined

我怎样才能使Rails特定@rails/ujs模块或所有模块可用?

在我的设置下面…</p>

应用程序/javascript/controllers/form_controller.js

import { Controller } from "stimulus"

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

应用程序/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))

应用程序/javascript/packs/application.js

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

谢谢!

4

5 回答 5

53

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

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

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

import Rails from '@rails/ujs';
于 2019-08-18T11:00:48.927 回答
18

首先,使用 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;

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

于 2019-09-30T04:21:48.240 回答
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']
    })
)
于 2019-06-10T22:09:35.780 回答
4

我目前在 6.0.0.rc2 上搞砸了,但我想我已经为你找到了答案。

因此,如果您将以下内容分开:

应用程序/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,这应该是你想要的 :)

让我知道这是否适合您!

于 2019-08-12T18:54:40.093 回答
1

我认为最好的方法是使用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这应该使您可以再次全局访问该对象。

于 2019-08-27T01:43:31.130 回答