Rails 6 Webpacker 从 Rails 视图调用 javascript 函数 [英] Rails 6 Webpacker calling javascript function from Rails view

查看:113
本文介绍了Rails 6 Webpacker 从 Rails 视图调用 javascript 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 Webpacker 的 Rails 6 应用程序中有以下 Javascript 结构.

I have following structure for Javascript in my Rails 6 app using Webpacker.

app/javascript
  + packs
    - application.js
  + custom
    - hello.js

下面是上面提到的JS文件中的内容

Below shown is the content in the above mentioned JS files

app/javascript/custom/hello.js

  export function greet(name) {
    console.log("Hello, " + name);
  }

app/javascript/packs/application.js

  require("@rails/ujs").start()
  require("jquery")
  require("bootstrap")

  import greet from '../custom/hello'

config/webpack/environment.js

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

const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
  })
)

module.exports = environment

现在在我的 Rails 视图中,我尝试使用导入的函数 greet,如下所示

Now in my Rails view I am trying to use the imported function greet like shown below

app/views/welcome/index.html.haml

  - name = 'Jignesh'

  :javascript

    var name = "#{name}"
    greet(name)

当我加载视图时,我在浏览器的控制台中看到 ReferenceError: greet is not defined 错误.

When I load the view I am seeing ReferenceError: greet is not defined error in browser's console.

我试图寻找这个问题的解决方案,并在网上找到了很多资源,但没有一个能帮助我.最后,当我在建议中起草这个问题时,我发现 How在 Rails 6 中执行自定义 javascript 函数,这确实接近我的需要但是该解决方案显示了一种解决方法,但我正在寻找合适的解决方案以满足需求,因为我有很多视图需要将数据从 Rails 视图传递给要移动 app/javascript/custom 文件夹下的自定义文件的 JS 函数.

I tried to search for a solution to this problem and found many resources on web but none turned out to help me. At last when I was drafting this question in the suggestions I found How to execute custom javascript functions in Rails 6 which indeed is close to my need however the solution shows a workaround but I am looking for a proper solution for the need because I have many views which needs to pass data from Rails view to JS functions to be moved custom files under app/javascript/custom folder.

另外,如果有人能帮助我理解我遇到的 ReferenceError 背后的原因,我将不胜感激.

Also I would highly appreciate if anybody can help me understand the cause behind the ReferenceError I am encountering.

注意:

我不精通 Node 领域的 Javascript 开发,也不太熟悉 Webpacker、Webpack、Javascript 的模块、importexportrequire 语法等所以如果你发现我问的有什么愚蠢的地方,请耐心等待.我在尝试升级现有 Rails 应用以使用版本 6 时遇到了上述情况.

I am not well-versed in Javascript development in Node realm and also new to Webpacker, Webpack, Javascript's modules, import, export, require syntax etc so please bear with me if you find anything silly in what I am asking. I have landed up in above situation while trying to upgrade an existing Rails app to use version 6.

推荐答案

默认情况下,Webpack 不会使模块可用于全局范围.也就是说,有几种方法可以在 AJAX 请求之外将信息从 Ruby 传递到 JavaScript:

Webpack does not make modules available to the global scope by default. That said, there are a few ways for you to pass information from Ruby to JavaScript outside of an AJAX request:

  1. window.greet = function() { ... } 并按照您的建议从视图中调用函数是一种选择.我不喜欢在很多地方编写副作用,所以这是我最不喜欢的.

  1. window.greet = function() { ... } and calling the function from the view as you have suggested is an option. I don't like have to code side effects in a lot of places so it's my least favorite.

你可以看看使用 expose-loader.这意味着自定义您的 webpack 配置以将选定模块中的选定功能公开"到全局范围.它可能适用于少数情况,但对于许多用例会变得乏味.

You could look at using expose-loader. This would mean customizing your webpack config to "expose" selected functions from selected modules to the global scope. It could work well for a handful of cases but would get tedious for many use cases.

从入口点导出选定的函数并配置 webpack 以打包 您的捆绑为图书馆.如果您更喜欢从视图中调用全局函数,这是我最喜欢的方法.我专门为 Webpacker 在我的博客.

Export selected functions from your entrypoint(s) and configure webpack to package your bundle as a library. This is my favorite approach if you prefer to call global functions from the view. I've written about this approach specifically for Webpacker on my blog.

// app/javascript/packs/application.js

export * from '../myGlobalFunctions'


// config/webpack/environment.js

environment.config.merge({
  output: {
    // Makes exports from entry packs available to global scope, e.g.
    // Packs.application.myFunction
    library: ['Packs', '[name]'],
    libraryTarget: 'var'
  },
})

// app/views/welcome/index.html.haml

:javascript
  Packs.application.greet("#{name}")

  • 完全采用不同的方法,将 Ruby 变量附加到控制器中的全局对象,例如使用 gon gem.假设您按照说明设置了 gem,gon 对象既可以作为 Ruby 对象使用,您可以在服务器端进行变异,也可以在您的 JavaScript 代码中作为全局变量读取.您可能需要想出一些其他方式来有选择地调用 greet 函数,例如对特定选择器的 DOM 查询仅在给定页面或给定 url 上呈现.

  • Take a different approach altogether and attach Ruby variables to a global object in your controller, such as with the gon gem. Assuming you setup the gem per the instructions, the gon object would be available both as Ruby object which you can mutate server-side and in your JavaScript code as a global variable to read from. You might need to come up with some other way to selectively call the greet function, such as with a DOM query for a particular selector that's only rendered on the given page or for a given url.

    # welcome_controller.rb
    
    def index
      gon.name = 'My name'
    end
    

    // app/javascript/someInitializer.js
    
    window.addEventListener('DOMContentLoaded', function() {
      if (window.location.match(/posts/)) {
        greet(window.gon.name)
      }
    })
    

  • 这篇关于Rails 6 Webpacker 从 Rails 视图调用 javascript 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆