javascript - Rails 6 Webpacker 从 Rails View 调用 javascript 函数

标签 javascript ruby-on-rails-6 webpacker

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

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

下图是上述JS文件中的内容

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 View 中,我正在尝试使用导入函数 greet,如下所示

app/views/welcome/index.html.haml

  - name = 'Jignesh'

  :javascript

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

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

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

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

注意:

我不精通 Node 领域的 Javascript 开发,也是 Webpacker、Webpack、Javascript 模块、importexportrequire 语法等,所以如果您发现我所问的内容有任何愚蠢之处,请多多包涵。我在尝试升级现有 Rails 应用程序以使用版本 6 时遇到了上述情况。

最佳答案

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

  1. window.greet = function() { ... } 并按照您的建议从 View 调用函数是一个选项。我不喜欢在很多地方编写副作用代码,所以这是我最不喜欢的。

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

  3. 从您的入口点导出选定的函数并配置 webpack 以打包 your bundle as a library .如果您更喜欢从 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}")
    
  4. 采用完全不同的方法,将 Ruby 变量附加到 Controller 中的全局对象,例如 gon gem .假设您按照说明设置 gem,gon 对象既可以作为 Ruby 对象使用,您可以在服务器端改变它,也可以在您的 JavaScript 代码中作为全局变量来读取。您可能需要想出一些其他方法来有选择地调用 greet 函数,例如对仅在给定页面或给定 url 上呈现的特定选择器进行 DOM 查询。

    # 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)
      }
    })
    

关于javascript - Rails 6 Webpacker 从 Rails View 调用 javascript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61777360/

相关文章:

ruby-on-rails - 如何在 Rails/Webpacker/React 应用程序中处理图像?

ruby-on-rails - 未定义 React Rails 组件

javascript - Angularjs + Kineticjs 鼠标事件

ruby-on-rails - 限制属性更新,但不限制创建,但更新无法更新时失败

javascript - 为新的 Rails 应用程序运行服务器时出现 Webpacker 错误

ruby-on-rails - Rails 6 + webpack 错误 : Uncaught TypeError: $(. ..).popover 不是函数

ruby-on-rails - 使用 Rails 6 实现 Google Adsense

javascript - 根据条件属性对对象进行排序

javascript - 如果点击目标是 iframe,则检测 div 外部的点击不起作用

javascript - z-index 的问题