我一般认为,如果没有破坏,请不要修复它,但我目前解决这个问题的方法(尽管它确实有效)似乎真的很难看。我正在使用Ruby,Sinatra,Haml和Highcharts,我希望能够传递Ruby中抓取的数据并发送给Highcharts。
目前,我基本上只是从整个Highcharts javascript中创建一个字符串对象,并将ruby数据插入其中。这有效,但我应该采取完全不同的方法吗?这正是我正在做的事情:
我已经定义了一个HighChart类,其中包含一些我希望能够通过Ruby更改的属性(例如图表标题,数据等)。下面的示例(有效!)仅设置其中两个属性,其余属性为默认值:
get '/' do
@chart = HighChart.new(options={
:title_text => "Test Title",
:series_data =>
{
'Calvin' => [10, 2, 17],
'Hobbes' => [11, 14, 6]
}
}
)
haml :index
end
我在视图中使用Haml的javascript过滤器:
:javascript
#{@chart.chart_js}
到目前为止一切顺利。丑陋的部分是chart_js方法。我只是简单地复制了HighChart javascript的全文,将其粘贴为字符串,然后使用Ruby插值从控制器中创建的HighChart对象中获取变量:
def chart_js
chart_js = "
var chart1;
$(document).ready(function() {
chart1 = new Highcharts.Chart({
chart: {
renderTo: '#{render_to}',
type: '#{chart_type}'
},
title: {
text: '#{title_text}'
},
xAxis: {
categories: #{x_categories}
},
yAxis: {
title: {
text: '#{y_categories}'
}
},
series: [#{get_data_js(series_data)}]
});
});
"
end
以防万一它有用,这是HighChart对象类定义的第一部分:
class HighChart
attr_accessor :render_to, :chart_type, :title_text, :x_categories,
:y_categories, :series_data
def initialize(options={})
self.render_to = options[:render_to] || 'container'
self.chart_type = options[:chart_type] || 'bar'
self.title_text = options[:title_text] || 'Fruit Consumption'
self.x_categories = options[:x_categories] || ['Apples', 'Bananas', 'Oranges']
self.y_categories = options[:y_categories] || 'Fruit eaten'
self.series_data = options[:series_data] || {'Jane' => [1, 0, 4],
'Bobbert' => [5, 7, 3],
'Zach' => [10, 2, 1]
}
end
答案 0 :(得分:3)
您可以专门为Highcharts JS制作视图,然后使用实例变量(例如@render_to,@ chart_type等)。这不会真正清理代码那么多,但它将摆脱在控制器中拥有巨大视图字符串的一些“错误”。
从根本上说,你可以做的事情不多;你有一堆服务器端信息,它必须写入客户端(以特定的Highcharts格式)。只是没有解决这个问题。
我能提供的唯一其他建议是使用中间JS变量。这将允许您在视图中保留所有JS(没有仅JS的视图),然后您只需要设置一些JS变量。这看起来像这样:
var RENDER_TO = "@render_to";
var CHART_TYPE = "@chart_type";
// ...
$(document).ready(function() {
chart1 = new Highcharts.Chart({
chart: {
renderTo: RENDER_TO,
....
现在这实际上涉及更多代码,但它可以让你完全将onReady代码与服务器值编写代码分开。
希望有所帮助。