0

我的主干视图(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参数(在上面的Backbone 视图中定义)中存在的 json 响应传递给一个名为chartData的变量,该变量在我的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)在我的萤火虫控制台中返回以下内容:-

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

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

4

1 回答 1

0

将“真正的”JavaScript 代码与您的模板混合(即,将 a<script>放入模板中,而不是简单的 JavaScript 部分用于将模板放在一起)通常效果不佳。如果您将关注点分开,您通常会更轻松:HTMLish 的东西放在模板中,功能连接在视图中。

我对 amChart 不是很熟悉,但是许多图表(和映射)库需要了解一些关于其目标元素的重要信息,然后才能进行任何工作。<div>特别是,他们通常会想知道它在页面上的位置以及它有多大,而这些在渲染到页面之前不会知道。render在 Backbone 应用程序中,在有人编辑视图并将其附加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 显然想要id它应该绘制到的 DOM 中的某些内容的额外困难:

chart.write("chartdiv");

但是直到 after被调用并且在某人完成了(或同等的)document.getElementById('chartdiv')之后才会返回任何有用的东西。renderx.append(v.el)

如果您希望有人el在调用后立即将您的视图显示到页面,render那么您可以排队一些代码以在浏览器重新获得控制权后运行(因此有时间弄清楚事物的大小和位置并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()并且仅在加载页面时触发(即在单页应用程序的持续时间内仅触发一次) . 您可能可以使用其他事件来代替,但您应该能够使用现有的 Backbone 视图结构,而不是依赖于文档就绪事件。

于 2013-09-09T05:16:05.523 回答