AngularJS数据绑定——观察周期不触发
AngularJS Data Binding - Watch cycle not triggering
假设如下JSFiddle: https://jsfiddle.net/pmgq00fm/1/
我希望我的NVD3图表实时更新,基于setInterval()在第39行更新指令绑定的数据。下面是架构和代码的快速指针:
- 该指令在ThisController 的作用域中。
- 使用指令 中的'='双向绑定数据
- 当指令在$watch周期中检测到数据的变化时,应该在图表上调用更新函数。
- $watch是一个深度表,所以值的变化应该被检测到
- 在指令中设置了一个间隔,以便在控制台中打印值的变化。每当调用updateFnc时,控制器都会打印更新后的数组。
- 指令中数据中的值永远不会与控制器中的数据匹配,原因我忽略了。
- 这些值可以在控制器和指令中修改。
- 指令中的$watch只在执行时调用 该代码基于本教程,并尊重其中解释的数据绑定所需的所有步骤。
要调试,请运行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);
}
};
}]);
任何帮助都将非常感激!非常感谢!
EDIT: New JSFiddle with Andrew Shirley的答案:https://jsfiddle.net/pmgq00fm/3/
添加一行
$scope.$apply()
到更新函数。这是因为当一个变量在javascript中被更新时,除了常见的angular函数之外,angular不会意识到这个变化,因此不会浪费任何精力来刷新DOM。这将强制执行一个应该刷新您所看到的内容的摘要循环。
编辑:真正理解为什么要使用作用域是非常重要的。我觉得我没有很好地描述它。这里有一篇文章比我写得好得多。
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html我指出这一点是因为你需要意识到,如果你在一个与angular密切相关的函数中(例如,由ng-click调用的东西),那么如果你试图使用作用域。$apply你会得到javascript错误,因为你已经处于摘要周期的中间。
相关文章:
- 在VanillaJS中模拟模型双向数据绑定
- Telerik rad组合框多列数据绑定
- 数据绑定:'系统Char'不包含名为'xxxxx'
- OnsenUI AngularJS数据绑定无法正常工作
- Ionic-item在导航栏中进行双向数据绑定
- 基本D3.js:如何将具有其他属性的数据绑定到元素
- 使用自定义数据属性或将数据绑定到处理程序来处理事件
- ListView的ItemTemplate内的自定义HtmlControl的数据绑定失败
- $http中的Angular 1数据绑定承诺不起作用
- 在何处和何时添加具有数据绑定的元素
- 使用AngularJs数据绑定的三元运算符显示图像
- 为什么针对工厂的Angular数据绑定只适用于函数
- 敲除:如何使用可见数据绑定可见来隐藏段落标记
- 挖空.js在数据绑定声明中分配可观察
- 数据绑定到可使用 javascript 在地铁风格的应用程序中观察到
- 使用剑道可观察数组、模板和数据绑定
- 在数据绑定表达式中,何时使用或不使用带可观察性的括号
- AngularJS数据绑定——观察周期不触发
- 了解如何使用element获取数据绑定键和值可观察对象
- JavaScript中简单的可观察双向数据绑定