【问题标题】:Using a Rails helper method within a javascript asset在 javascript 资产中使用 Rails 辅助方法
【发布时间】:2011-11-19 01:45:45
【问题描述】:

有什么方法可以使用 Rails 辅助方法,更具体地说,是 javascript 资产文件中的路径辅助方法。这个文件foo.js.coffee.erb

$('#bar').val("<%= create_post_path %>")

如果我能从 erubis 获得,我会很高兴的

$('#bar').val("path/to/create")

【问题讨论】:

  • 您尝试过这样做吗?它应该可以工作。
  • 是的,我试过了,它给出了“未定义的局部变量或方法”。我尝试过其他方法,例如... number_to_currency
  • 我想指出,这个辅助方法确实有效:javscript_path('path/to/js')

标签: javascript ruby-on-rails ruby-on-rails-3 asset-pipeline erubis


【解决方案1】:

您可以在 erb 模板中包含任何帮助程序/模块/类:

<% environment.context_class.instance_eval { include MyHelper } %>

请参阅:https://github.com/rails/sprockets/blob/master/lib/sprockets/environment.rbhttps://github.com/rails/sprockets/blob/master/lib/sprockets/context.rb

要使用 url 助手,您必须包含特定应用程序的助手。

他们可以在Rails.application.routes.url_helpers 获得,所以:

<% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %>

编辑:修复了移动链轮存储库的链接,但不确定多年后这仍然有意义。

【讨论】:

  • 但是如何包含 UrlHelpers 模块?这样做的坏处是 url 助手在运行时需要一个模型,buy-buy cowboy
  • 要使用 url 助手,您必须包含特定应用程序的助手。它们可在Rails.application.routes.url_helpers 获得,所以:&lt;% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %&gt;
  • 绝妙的答案!你是怎么想出来的?这是出现在 Rails 指南中的吗?我想我可能在 RailsCast 中看到过类似的东西,这个魔法太强大了,你得告诉我!
  • 不知道我到底是怎么想出来的,但要么通过浏览 Rails 代码(IntelliJ IDE (jetbrains.com/idea) 使这成为可能且非常简单),要么在调试模式下运行(赞美再次使用 IDE :)
  • github 链接返回 404 :(
【解决方案2】:

这也将在初始化程序中发挥作用:

Sprockets::Context.send :include, MyHelper

在开发模式下,助手不会在每次请求时都重新加载。

在您需要找到 post_path(...um...we don't know what post id we'll need at compile time...) 之前,您使用 UrlHelpers 的方法将一直有效。有一个 ruby​​ gem 可以用 JavaScript 重新实现所有 Rails UrlHelpers:https://github.com/railsware/js-routes

【讨论】:

  • 由于我使用的是 config.assets.initialize_on_precompile = false ,因此我不得不在我的 application.rb 文件中添加一个 railtie。 stackoverflow.com/questions/9235292/… 关于如何设置 railtie。
【解决方案3】:

我不太确定,您为什么要这样做。

  • 你会阻止 javascript 文件被缓存,因为它包含一个动态值

  • 您的 javascript/coffeescript 和 rails 之间会有一个耦合

如果可能的话,我建议您通过在视图中提供目标路径并在特定事件发生时从 DOM-Element 检索值来抽象出您的问题。就像 Rails 的“Unobtrusive Scripting Adapters”一样。例如:https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L157-173

【讨论】:

  • 这不会阻止缓存。资产在部署时被编译并且永远不会改变该路径不会改变(除非它真的改变并且资产被重新编译)如果你想在你的 JS 中使用一个从你的@987654322 托管的图像路径,这将特别有用@
  • 如上所述,我不想这样做,因为它会在您的应用程序和 JavaScript 之间引入耦合。你的应用程序的每个部分都应该服务于不同的目的。您不希望您的视图具有模型逻辑,我个人也不希望 Rails 代码泄漏到我的 JavaScript 中。当然,这是一种个人喜好。 JavaScript 有许多可能从 DOM 中检索信息,而无需直接注入其中。您不希望对这些值进行硬编码。那么为什么让一个帮手为你做这件事会更好呢?
  • 第一次发布时,github 链接最初指向的代码在哪里?拥有指向“master”分支的链接会使它们在一段时间后难以遵循。
【解决方案4】:

确实,我同意@eirc 的回答(考虑到 Sprockets 文档)。但我会 考虑在 rails 启动时包含辅助模块。根据

# config/initializers/sprockets.rb
Rails.application.assets.context_class.instance_eval do
  include ActionView::Helpers
  include Rails.application.routes.url_helpers
  include MyModule
end

这是因为:https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L23

【讨论】:

    【解决方案5】:

    实际上,不确定这是否有帮助,但有一种方法可以定义您自己的助手以在rake precompile 期间使用

    创建一个新的初始化器并将其放入其中:

    module Sprockets
      module Helpers
        module RailsHelper
    
          def my_helper_method
           ...
          end
    
        end
      end
    end
    

    然后你可以:

    <%= my_helper_method %>
    

    在您的 .erb 资产中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      相关资源
      最近更新 更多