Knockout.js 杜兰达尔淘汰赛

Knockout.js 杜兰达尔淘汰赛,knockout.js,durandal,jchartfx,knockout-extensions,Knockout.js,Durandal,Jchartfx,Knockout Extensions,我正在尝试将这个组件jchartfx与Durandel集成。我有一个独立的原型,没有使用Durandel,使用knockout,它工作得非常完美,所以我相信这个问题与Durandel有关 以下是我的viewmodel代码: define(function (require) { var http = require('durandal/http'); var serverUrl = '/api/burndown'; var chart1; function bu

我正在尝试将这个组件jchartfx与Durandel集成。我有一个独立的原型,没有使用Durandel,使用knockout,它工作得非常完美,所以我相信这个问题与Durandel有关

以下是我的viewmodel代码:

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;
});
定义(功能(需要){
var http=require('durandal/http');
var serverUrl='/api/burndown';
var-chart1;
函数burnDownModel(){
var self=这个;
self.initilize=true;
self.displayName='Burndown Chart';
self.description=‘燃尽图’;
self.chartData=ko.observearray([]);
self.viewAttached=函数(){
};
//假数据测试
self.activate=函数(){
返回http.get(serverUrl).then(函数(响应){
对于(变量i=0;i<10;i++){
风险值数据={
“日期”:“2013-02-18T00:00:00”,
“DevCurrentEstimates”:6.5,
“TestCurrentEstimates”:7.5,
“原始估算”:8.5,
“TestOriginalEstimates”:9.5
};
self.chartData.push(数据);
}
ko.bindingHandlers.jchartFx={
init:函数(元素、值访问器){
chart1=新的cfx.Chart();
图表1.getData().setSeries(4);
图表1.getAxisX().getLabelsFormat().setFormat(cfx.AxisFormat.Date);
图表1.getAxisX().getLabelsFormat().setCustomFormat(“MMM dd”);
调试器;
var value=ko.utils.unwrapobbservable(valueAccessor());
图1.setDataSource(值);
图1.创建(元素);
}
};
});
};
};
返回燃耗模型;
});
还有我的html绑定

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

正如我所说,我在没有杜兰德尔的情况下工作

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

<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>

$(函数(){
var viewModel={
图表数据:ko.observearray([])
};
LoadChartData();
函数LoadChartData(){
对于(变量i=0;i<10;i++){
var图表数据={
“日期”:“2013-02-18T00:00:00”,
“DevCurrentEstimates”:6.5,
“TestCurrentEstimates”:7.5,
“原始估算”:8.5,
“TestOriginalEstimates”:9.5
};
viewModel.chartDatas.push(chartData);
}
}
应用绑定(视图模型);
});
我能看到的唯一区别是,这个脚本在页面加载时运行,而且我必须手动应用ko绑定,而不是Durandel为我这样做。
我没有发现任何错误,只是没有显示图表数据

问题似乎与视图尚未连接到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
,另外,您可能希望从其他视图模型中使用它。

问题似乎与视图尚未连接到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
,另外,你可能想从其他视图模型中使用它。

在你的代码中,第一件事就是将图表数据更改为可观察的。使用jchartfx时,它需要单个对象数组(json),而不是对象数组。我将一个数组传递给chartData observable

在KnockoutbindingHandler中添加一个“更新”,并在那里执行图表创建方法。当您从viewModel中的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>

在代码中的第一件事是,将图表数据更改为可观察数据。使用jchartfx时,它需要单个对象数组(json),而不是对象数组。我将一个数组传递给chartData observable

将“更新”添加到您的KnockoutbindingHandler中,并执行图表创建方法