我正在尝试将这个组件jchartfx与Durandel集成。我有一个使用knockout的独立原型,没有Durandel,它工作得很好,所以我相信这个问题与Durandel有关。
下面是我的视图模型代码:
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为我做这件事。我没有得到任何错误,只是没有显示图表数据。
发布于 2013-04-17 06:13:13
在您的代码中,第一件事是将chartData更改为可观察对象。对于jchartfx,它需要单个对象数组(json),而不是对象数组。我将一个数组传递给chartData observable。
向您的Knockout bindingHandler添加一个“更新”,并在那里执行图表创建方法。当您从viewModel中的viewAttached方法或afterBind获取数据时,这将被触发。由于viewAttached的目标是将Durandal绑定到DOM,因此您的图表将按预期显示。
viewModel文件
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>发布于 2013-04-17 04:23:17
问题似乎与尚未附加到DOM的视图有关。
一种可能的解决方案是在viewModel中创建一个属性来指示视图是否已附加,并修改绑定,以便在附加视图之前不会创建图表。
//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属性的辅助绑定,然后通过allBindingsAccessor参数从jchartFx绑定访问它。这样,所有的视图模型属性依赖关系都是公开的,并且更容易知道发生了什么。
无论如何,我强烈建议将绑定从激活函数中移出-理想情况下,将绑定移到应用程序首次加载时执行的全局脚本中。你真的只想设置ko.bindingHandlers.jchartFx一次以上,你可能想要在其他视图模型中使用它。
https://stackoverflow.com/questions/16042362
复制相似问题