我正在编写DagreD3的AngularJS指令。我在Angular中使用$ scope更新时遇到了一些问题。当我更新模型时,指令不会重新渲染图形。
我的指示如下:
myApp.directive('acDagre', function() {
function link(scope, element, attrs) {
scope.$watch(scope.graph, function(value) {
alert('update'); //NOT EVEN THIS IS CALLED ON UPDATE
});
var renderer = new dagreD3.Renderer();
renderer.run(scope.graph, d3.select("svg g"));
}
return {
restrict: "A",
link: link
};
变量$ scope.graph在运行时在Controller中被修改,如下所示:
$scope.addNode = function(){
$scope.graph.addNode("kbacon2", { label: "Kevin Bacon the second" });
}
我对Angular有什么不妥吗?每次更改Variable $ scope.graph时,我都希望图表更新。 您可以在Plunker中找到更多信息。
非常感谢你的帮助!
答案 0 :(得分:1)
观察者应该看起来像这样:
scope.$watch('graph', function(value) {
console.log('update');
});
或者像这样:
scope.$watch(function () { return scope.graph; }, function(value) {
console.log('update');
});
添加节点时不会触发,导致它通过引用进行比较。
您可以添加true
作为第三个参数来执行深度监视(它将使用angular.equals
):
scope.$watch('graph', function(value) {
console.log('update');
}, true);
请注意,这样更贵。
示例:
.directive('acDagre', function() {
var renderer = new dagreD3.Renderer();
function link(scope, element, attrs) {
scope.$watch(function () { return scope.graph; }, function(value) {
render();
}, true);
var render = function() {
renderer.run(scope.graph, d3.select("svg g"));
};
}
return {
restrict: "A",
link: link
};
});
演示:http://plnkr.co/edit/Dn1t3sMH58mDz9HhqYD5?p=preview
如果您只是更改节点,则可以改为定义watchExpression
:
scope.$watch(function () { return scope.graph._nodes; }
深度观看大型物体会对性能产生负面影响。这当然取决于被监视对象和应用程序的大小和复杂程度,但是要注意这一点很好。