Rails 3.1资产管道中的客户端动态资产URL

时间:2011-11-14 19:35:31

标签: ruby-on-rails ruby-on-rails-3.1 asset-pipeline

TL; DR

我正在尝试在客户端使用HTML5数据元素动态生成资产URL。这意味着资产名称在浏览器运行时才可用,这会阻止ERB在服务器上进行预处理。

处理这种情况是否有解决办法或最佳做法?

背景

我在Rails应用程序中使用Fusion Charts图表插件,该应用程序使用各种SWF文件生成图表。我正在将应用程序升级到Rails 3.1并将这些SWF文件放入/vendor/assets/javascripts/fusion_charts

在应用程序中,我使用HTML5数据属性动态指定要绘制的图表类型,如下所示:

<%# ... metric.html.erb ... %>
<div id='chart-container' class='fusion-chart'
  data-chart-type='MSLine'
  data-source-url="<%= @metric.data_url %>">

然后我有一个用CoffeeScript编写的简单jQuery插件,它可以提取这些数据属性并将内容连接到Fusion Charts:

// ... charting_plugin.js.coffee ...
chart = new FusionCharts
  swfUrl: "/assets/fusion_charts/#{data.chartType}.swf"
chart.setJSONUrl data.sourceUrl
chart.render containerId

我遇到的问题是swfUrl参数。要遵循RoR Asset Pipeline guide中提供的指导,我应该在ERB中使用asset_path帮助程序,但这不起作用,因为data.chartType在运行时绑定在客户端上,并且无法在服务器端进行预处理。

<# ... charting_plugin.js.coffee.erb: This won't work; data.chartType isn't defined ... %>
chart = new FusionCharts
  swfUrl: "<%= asset_path "fusion_charts/#{data.chartType}.swf" %>"
chart.setJSONUrl data.sourceUrl
chart.render containerId

解决方法

最简单的解决方法(我当前使用的是)只需将SWF文件移回/public/fusion_charts,而不用担心资产指纹识别管道的复杂性。也就是说,我是管道新手,所以也许我错过了一些明显的东西。

有没有更好的方法来处理像这样的客户端资产网址?

1 个答案:

答案 0 :(得分:3)

一种解决方案是按图表类型为swf文件设置查找表,例如:

var chartMap = {
<% 
chart_types.collect do |type|
  "#{type.to_json}: #{asset_path(type + '.swf')}"
end.join(",\n")
%>
};

然后添加一个函数以在运行时在客户端获取正确的路径,如下所示:

function chartPath(type) {
  return chartMap[type];
};

然后将您的设置调用更改为:

chart = new FusionCharts
  swfUrl: chartPath(data.chartType)

IE,使用ERB构建资产编译时需要的所有可能路径的列表,然后在运行时在客户端上进行查找。 (当然,你需要咖啡脚本 - 上面的 - 我不是咖啡人,我更喜欢拿铁咖啡。: - )