2013-04-16 72 views
1

我正在尝试将此组件jchartfx与Durandel集成。我有一个独立的原型,使用没有杜兰德尔的淘汰赛,并且工作完美,所以我确信这个问题与杜兰德尔相关。Durandal淘汰赛jchartfx

这里是我的视图模型代码:

define(function (require) { 
    var http = require('durandal/http'); 
    var serverUrl = '/api/burndown'; 
    var chart1; 

    function burnDownModel() { 
     var self = this; 
     self.initilize = true; 
     self.displayName = 'Burndown Chart'; 
     self.description = 'Burndown Chart'; 
     self.chartData = ko.observableArray([]); 
     self.viewAttached = function() { 

     }; 

     // testing with fake data 
     self.activate = function() { 
      return http.get(serverUrl).then(function (response) { 

       for (var i = 0; i < 10; i++) { 
        var data = { 
         "Date": '2013-02-18T00:00:00', 
         "DevCurrentEstimates": 6.5, 
         "TestCurrentEstimates": 7.5, 
         "DevOriginalEstimates": 8.5, 
         "TestOriginalEstimates": 9.5 
        }; 


        self.chartData.push(data); 
       } 

       ko.bindingHandlers.jchartFx = { 
        init: function (element, valueAccessor) { 
         chart1 = new cfx.Chart(); 
         chart1.getData().setSeries(4); 
         chart1.getAxisX().getLabelsFormat().setFormat(cfx.AxisFormat.Date); 
         chart1.getAxisX().getLabelsFormat().setCustomFormat("MMM-dd"); 
         debugger; 

         var value = ko.utils.unwrapObservable(valueAccessor()); 
         chart1.setDataSource(value); 
         chart1.create(element); 
        } 
       }; 
      }); 
     }; 
    }; 

    return burnDownModel; 
}); 

和我的HTML结合

<div id="ChartDiv1" class="chartdiv" data-bind="jchartFx:chartData"style="width:550px;height:400px;display:inline-block"></div> 

正如我说我有这个工作没有Durandel。

下面是该解决方案的脚本:

<script type="text/javascript"> 

    $(function() { 
     var viewModel = { 
      chartDatas: ko.observableArray([]) 
     }; 
     LoadChartData(); 

     function LoadChartData() { 
      for (var i = 0; i < 10; i++) { 
       var chartData = { 
        "Date": '2013-02-18T00:00:00', 
        "DevCurrentEstimates": 6.5, 
        "TestCurrentEstimates": 7.5, 
        "DevOriginalEstimates": 8.5, 
        "TestOriginalEstimates": 9.5 
       }; 
       viewModel.chartDatas.push(chartData); 
      } 
     } 

     ko.applyBindings(viewModel); 
    }); 

</script> 

我能看到的唯一区别是,运行此脚本时,页面加载和我也有手动应用KO绑定,而不是Durandel做为了我。 我没有收到任何错误,只是没有显示图表数据。

+0

我不知道到底为什么图表没有渲染,但似乎与DOM定时做。如果你把'chart1。在setTimeout中创建(元素)'调用像这样'setTimeout(function(){chart1.create(element);},100);',它似乎工作。 –

+0

jchartfx假定它使用完整的DOM。在Durandal中,绑定是相对于尚未成为DOM的一部分的文档片段,直到初始绑定之后。 – mikekidder

回答

1

您的代码的第一件事,在chartData更改为可观察到的。与jchartfx它期待一个单一的对象数组(json),而不是一个对象数组。我将单个数组传递给chartData observable。

向您的Knockout添加“更新”bindingHandler并在那里执行图表创建方法。当您获取您的数据无论从viewAttached方法或在您的视图模型afterBind这将被解雇。由于viewAttached是在Durandal绑定到DOM之后,您的图表将按预期显示。

视图模型文件

define(function (require) { 

    var system = require('durandal/system'); 
    var http = require('durandal/http'); 

    // KO observables & bindings 
    var errorMessage = ""; 
    var pageTitle = "jChartFX Demo"; 
    var chartData = ko.observable(); 

    function LoadServerData() { 

     // Your server request can go here; 
     var items = [{ 
      "Date": '2013-02-18T00:00:00', 
      "DevCurrentEstimates": 6.5, 
      "TestCurrentEstimates": 7.5, 
      "DevOriginalEstimates": 8.5, 
      "TestOriginalEstimates": 9.5 
     },{ 
      "Date": '2013-02-18T00:00:00', 
      "DevCurrentEstimates": 6.5, 
      "TestCurrentEstimates": 7.5, 
      "DevOriginalEstimates": 8.5, 
      "TestOriginalEstimates": 9.5 
     },{ 
      "Date": '2013-02-18T00:00:00', 
      "DevCurrentEstimates": 6.5, 
      "TestCurrentEstimates": 7.5, 
      "DevOriginalEstimates": 8.5, 
      "TestOriginalEstimates": 9.5 
     }] 
     chartData(items); 
    } 

    var activate = function(view) { 
     system.log("view activated"); 
     return; 
    } 

    var viewAttached = function (view) { 
     LoadServerData(); 
     system.log("viewAttached loaded"); 
     return; 
    } 

    return { 
     pageTitle: pageTitle, 
     chartData: chartData, 
     activate: activate, 
     viewAttached: viewAttached 
    } 
}); 

ko.bindingHandlers.jchartFx = { 
    init: function (element, valueAccessor) { 
     chart1 = new cfx.Chart(); 
     chart1.getData().setSeries(4); 
     chart1.getAxisX().getLabelsFormat().setFormat(cfx.AxisFormat.Date); 
     chart1.getAxisX().getLabelsFormat().setCustomFormat("MMM-dd"); 
     debugger; 
    }, 
    update: function (element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     chart1.setDataSource(value); 
     chart1.create(element); 
    } 
}; 

和视图文件

<div> 
    <h2 data-bind="text: pageTitle"></h2> 
    <div id="ChartDiv1" class="chartdiv" data-bind="jchartFx: chartData" style="width:550px;height:400px;display:inline-block"></div> 
</div> 
0

这个问题似乎与没有尚未连接到DOM的观点做。

一个可能的解决方案是建立在您的视图模型指示视图是否已附加的属性,并修改绑定,这样的图表还没有生成,直到视图连接。

//in view model 
isViewAttached = ko.observable(false); 
self.viewAttached = function() { 
    self.isViewAttached(true); 
}; 


//in binding 
ko.bindingHandlers.jchartFx = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     ... 
     viewModel.isViewAttached.subscribe(function() { 
      $(element).chart(); 
     }); 
     ... 

虽然这可能不是最好的主意,因为它依赖视图模型中的“魔术”属性。

一个更好的办法可能是创建一个辅助的结合,你可以直接绑定到isViewAttached财产,并从jchartFx访问它通过allBindingsAccessor参数绑定。通过这种方式,所有视图模型属性依赖关系都处于公开状态,并且更容易分辨发生了什么。

无论如何,我强烈建议移出激活功能的结合 - 理想为第一次加载应用程序当这样执行的全局脚本。你真的只想设置ko.bindingHandlers.jchartFx一次 - 另外,你可能想从其他视图模型中使用它。