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

时间:2019-05-14 10:17:59

标签: 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")

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

ReferenceError: Rails is not defined

如何使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")
  }
  // ...
}

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"

谢谢!

5 个答案:

答案 0 :(得分:10)

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

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

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

import Rails from '@rails/ujs';

答案 1 :(得分:5)

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

然后: 这是结果-> My result when i typed Rails in Firefox Console

答案 2 :(得分:2)

我目前正忙于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)
  }
}

只需在这里使用他们的小测试控制器,但我将其控制台登录即可,您可以调用rails_ujs.fire,这应该是您想要的:)

让我知道这是否适合您!

答案 3 :(得分:1)

只需将其添加到您的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']
    })
)

答案 4 :(得分:0)

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


安装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'
       }]
    }
    

将该加载程序添加到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对象。