2013-04-16 139 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一次 - 另外,你可能想從其他視圖模型中使用它。