【发布时间】:2016-01-14 15:32:24
【问题描述】:
假设以下 JSFiddle:https://jsfiddle.net/pmgq00fm/1/
我希望我的 NVD3 图表实时更新,基于第 39 行的 setInterval() 更新指令绑定到的数据。 以下是有关架构和代码的快速提示:
- 指令在 ThisController 的范围内
- 使用指令中的“=”双向绑定数据
- 只要指令在 $watch 周期内检测到数据发生变化,就应该在图表上调用更新函数。
- $watch 是深度手表,因此应该检测值的变化
- 在指令中设置了一个间隔以在控制台中打印值的变化。每当调用 updateFnc 时,控制器都会打印更新后的数组。
- 由于某种原因,我忽略了指令 never 中的数据值与控制器中的数据匹配。
- 值在控制器和指令中都被修改。
- 指令中的 $watch 仅在执行时调用
- 代码基于this tutorial,并遵循其中解释的数据绑定所需的所有步骤。
要调试,请运行 JSFiddle 并打开控制台以查看对象和调试打印。
HTML:
<div id="stats-container" ng-app="myApp" ng-controller="ThisController">
<div id="nvd3-test" nvd3-discrete-bar data="data.graph">
</div>
JS:
myControllers.controller('ThisController', ['$scope', function ThisController($scope){
$scope.data = { graph : [ ... ] };
updateFnc = function(data){
for(var i = 0; i < data[0].values.length ; i++){
data[0].values[i].value = Math.random();
}
console.log(Date.now()/1000 + ": In Controller");
console.log(data);
};
setInterval(function(){
updateFnc($scope.data.graph);
}, 1000);
}]);
myServices.factory('NVD3Wrapper', ['NVD3S', 'D3S', '$q', '$rootScope', function NVD3Wrapper(nvd3s, d3s, $q, $rootScope){
return {
nvd3: nvd3s,
d3: d3s,
discreteBarChart : function(data, config){
var $nvd3 = this.nvd3,
$d3 = this.d3,
$nvd3w = this, //In order to resolve the nvd3w in other scopes.
d = $q.defer(); //Creating a promise because chart rendering is asynchronous
$nvd3.addGraph(function() {
...
});
return {
chart: function() { return d.promise; } //returns the chart once rendered.
};
},
_onRenderEnd: function(d, chart){
$rootScope.$apply(function() { d.resolve(chart); });
},
};
}]);
myDirectives.directive('nvd3DiscreteBar', ['NVD3Wrapper', function(nvd3w){
return {
restrict: 'EA',
scope: {
data: '=' // bi-directional data-binding
},
link: function(scope, element, attrs) {
var chart,
config = {
target: element,
};
var wrapper = nvd3w.discreteBarChart(scope.data, config);
wrapper.chart().then(function(chart){
scope.$watch(function() { return scope.data; }, function(newValue, oldValue) {
console.log(Date.now()/1000 + ": In Directive $watch");
if (newValue)
chart.update();
}, true);
});
//For testing
setInterval(function(){ console.log(Date.now()/1000 + ": In Directive"); console.log(scope.data); }, 1000);
}
};
}]);
任何帮助将不胜感激!非常感谢!
编辑:新的 JSFiddle 与 Andrew Shirley 的回答:https://jsfiddle.net/pmgq00fm/3/
【问题讨论】:
标签: javascript angularjs d3.js nvd3.js