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

How to convert [object Object] in Backbone to actual data

本文关键字:object 转换 数据 Backbone 中的      更新时间:2023-09-26

我的Backbone视图(file.js)中有一个函数,该函数由以下格式的JSON响应填充:-

主干视图中的功能:-

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参数(在上面的主干视图中定义)中存在的json响应传递给名为chartDatast.ejs模板(下面的代码)中定义。这个变量(chartData)被我的AM charts JS代码用来实际绘制图表。

我的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变量在我的firebug控制台中返回以下内容,而不是将实际数据作为all_stats(shown_above)的一部分:-

chartData: [object Object],[object Object],[object Object],[object Object],[object Object]

如何将graph_data变量中存在的实际数据(作为主干视图的一部分)正确分配给jst.ejs模板中存在的变量chartData

将"真实"的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)(或等效操作)之后才会返回任何有用的内容。

如果你希望有人在调用render后立即将你的视图的el放到页面上,那么你可以在浏览器恢复控制后排队运行一些代码(因此有时间计算事物的大小和位置,并使document.getElementById('chartdiv')做一些有用的事情),方法是使用setTimeout,超时为零:

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特定的东西需要处理,但希望这能解决困难的部分。

顺便说一句,你在评论中提到的AmCharts.ready调用可能不太适用于单页应用程序,因为它可能相当于$(document).ready(),并且只有在加载页面时才会触发(即在单页应用的持续时间内只触发一次)。您可能还可以使用其他事件,但您应该能够使用现有的主干视图结构,而不是依赖于文档就绪事件。