我的Backbone视图(file.js)中有一个函数,其中填充了以下格式的JSON响应: -
Backbone View中的功能: -
chart_data: function(){
var all_stats = this.collection.toJSON();
$("#page-container").html(this.users_by_loc({
platform_stats: all_stats,
graph_data: all_stats.items.slice(0,5)
// I want to use the top 5 entries to plot graph
}));
}
响应作为 all_stats 的一部分出现(来自我的api调用 - 我在服务器端使用Rails): -
{
"items":
[
{
"loc": "Chennai",
"users": 11707
},
{
"loc": "Hyderabad",
"users": 4327
},
{
"loc": "Pune",
"users": 3625
},....(many more entries)
]
}
现在,我正在尝试将 graph_data 参数(在我的 Backbone视图中定义)中的json响应传递给名为 chartData <的变量/ strong>在我的 jst.ejs 模板中定义(下面的代码)。我的AM图表JS代码使用此变量(chartData)来实际绘制图形。
我的 jst.ejs 文件,其中包含填充图表数据并绘制图表的代码,如下所示: -
<script>
var chart;
chartData = "<%= graph_data %>"
console.log("chartData: ", chartData);
AmCharts.ready(function () {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
//additional code to help plot the chart
chart.write("chartdiv");
});
</script>
<div id="chartdiv" style="width: 60%; height: 400px;"></div>
我的目前的障碍是我做的时候..
chartData = "<%= graph_data %>"
console.log("chartData: ", chartData);
..在我的jst.ejs模板中,chartData变量而不是将实际数据作为 all_stats (shown_above)的一部分,在我的firebug控制台中返回以下内容: -
chartData: [object Object],[object Object],[object Object],[object Object],[object Object]
如何将 graph_data 变量(作为主干视图的一部分)中的实际数据正确分配到变量 chartData 出现在我的 jst.ejs 模板中以绘制图表?
答案 0 :(得分:0)
将“真正的”JavaScript代码与模板混合(即将<script>
投入到模板中,而不是简单的JavaScript用于将模板放在一起)通常不能很好地解决问题。如果你把问题分开,你通常会有一个更轻松的时间:模板中有HTML事情,视图中有功能。
我对amChart并不熟悉,但是许多图表(和映射)库需要先了解一些有关其目标元素的重要信息才能完成任何工作。特别是,他们通常想要知道它在页面上的位置以及它有多大,并且在<div>
呈现到页面之前不会知道这些内容。在Backbone应用程序中,在有人render
将视图和附加到页面的el
之前,这通常不会成立:
var v = new View;
// We don't know the position or size of anything yet.
v.render();
// We still don't know.
$('body').append(v.el);
// Now the size and position are available but we might have to
// pass control back to the browser first.
你正面临着amChart显然想要它应该吸引的DOM中id
内容的额外难度:
chart.write("chartdiv");
但是document.getElementById('chartdiv')
在调用render
之后以及有人完成x.append(v.el)
(或等效)之后才会返回任何有用的内容。
如果您希望有人在调用el
之后立即将您的视图render
发送到该页面,那么您可以在浏览器获得控制权后排队一些代码以便运行(因此有时间弄清楚事物的大小和位置,并使setTimeout
with a timeout of zero使document.getElementById('chartdiv')
做一些有用的事情:
render: function() {
var _this = this;
var chartData = ....
// Do normal rendering and template stuff.
setTimeout(function() {
var chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
//...
chart.write("chartdiv");
}, 0);
return this;
}
如果您想更加明确一点,也可以使用_.defer
(只有setTimeout(..., 1)
)。
可能会有一些特定于amChart的东西要处理,但希望这会照顾到困难的部分。
BTW,您在评论中提到的AmCharts.ready
调用可能与单页应用程序的效果不佳,因为它可能等同于$(document).ready()
并且仅在加载页面时触发(即在单页应用程序的持续时间内只有一次)。您可以使用其他可以使用的事件,但您应该能够使用现有的Backbone视图结构,而不是依赖于文档就绪事件。