如何将Backbone中的[object Object]转换为实际数据

时间:2013-09-04 09:59:30

标签: javascript json backbone.js backbone-views amcharts

我的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 模板中以绘制图表?

1 个答案:

答案 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视图结构,而不是依赖于文档就绪事件。