【问题标题】:Rails/Javascript: How to inject rails variables into (very) simple javascriptRails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
【发布时间】:2011-11-21 14:19:40
【问题描述】:

我想在 rails 中编写一个非常简单的 javascript 计算器,它将输入字段的数量乘以存储在 rails 变量 (@item.base_price) 中的数字

所以,在 javascript/coffeescript 方面,大致是这样的:

# app/assets/javascript/items.js.coffee
$ -> 
  $('#item_quantity').change ->
    quantity_val = $(this).val()
    $('#total_amount').html(quantity_val * <%= I_WANT_@ITEM.BASE_PRICE_HERE %>)

我知道如何通过对每个 change() 调用的 ajax 调用来做到这一点,但我认为必须有一种优雅的、希望不引人注意的 rails 方式,它不会每次都访问服务器。

非常感谢任何建议

【问题讨论】:

    标签: javascript ruby-on-rails coffeescript


    【解决方案1】:

    使用资产管道在每个请求的基础上使用 ERB 处理 CoffeeScript 文件可能适合开发,但它会成为生产中的瓶颈。

    在生产中,我使用全局变量或全局变量的特定属性来减少污染。

    在页面底部的 ERB 视图:

    <script>
      //<![CDATA[
        window.MyApp = window.MyApp || {};
        window.MyApp.itemBasePrice = <%=j @item.base_price.to_json.html_safe %>;
      //]]>
    </script>
    

    始终将脚本放在页面底部(并将样式表放在顶部),因为这样会加快页面加载时间。

    我强烈推荐在How to securely bootstrap JSON in a Rails view 上阅读这篇文章。在撰写本文时,最新版本的 Rails 在以这种方式引导 JSON 时容易受到 XSS 攻击。如果您只有一个简单的数字,那可能不是问题。但我发现人们看到你的代码正常工作后,往往会简单地将其复制/粘贴到更复杂的情况下,而不考虑后果。

    或者,如果您的数据具有自然容器,您可以将其嵌入数据属性中。

    <div id="item" data-base-price="<%=j @item.base_price.to_json.html_safe %>"></div>
    

    在你的 CoffeeScript 中访问它:

    console.log $('#item').data('basePrice')
    

    【讨论】:

      【解决方案2】:

      虽然...如果您将 Javascript 文件作为静态资产提供,这可能不是最佳选择。我通常在带有变量的 HTML 的head 部分中放置一个script 标记。这样,JS 就不必重新构建,并且浏览器缓存也不会失效。例如:

      <head>
        <script type="text/javascript">
          var myGlobalVariable = <%= @global_js_variable %>;
        </script>
      </head>
      

      虽然将事物保存在单独的命名空间中很糟糕,但它确实减少了向客户端发送新的 Javascript 文件的开销。

      只是一个想法。

      【讨论】:

      • 虽然把东西放在单独的命名空间里很臭 使用 setter 保持根命名空间干净:SomeExistingGlobalVar.my_variable = &lt;%= @my_variable %&gt;;
      【解决方案3】:

      如果您使用的是 rails 3.1,您可以利用资产管道在提供 javascript 文件之前对其进行一些预处理。为此,只需将文件扩展名更改为:

      items.js.coffee
      

      items.js.coffee.erb
      

      然后您可以将 ruby​​ 添加到您的 javascript 中,就像在您的视图中使用 &lt;%= %&gt; 标记一样。您可能遇到的唯一问题是您的 items.js 文件将被提供给对您应用程序的任何控制器方法的每个请求。所以最好写一个辅助方法,只有当实例变量被初始化时才会返回值

      例如在 items_helper.rb 中

      def item_price
          if @item
              @item.base_price
          else
              0
          end
      end
      

      编辑:更多关于资产管道的信息:

      http://guides.rubyonrails.org/asset_pipeline.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        相关资源
        最近更新 更多