集成AngularJS和DagreD3 - AngularJS指令不会更新模型更改。

时间:2014-05-05 09:46:27

标签: angularjs d3.js

我正在编写DagreD3的AngularJS指令。我在Angular中使用$ scope更新时遇到了一些问题。当我更新模型时,指令不会重新渲染图形。

A plunker can be found here.

我的指示如下:

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中找到更多信息。

非常感谢你的帮助!

1 个答案:

答案 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; }

深度观看大型物体会对性能产生负面影响。这当然取决于被监视对象和应用程序的大小和复杂程度,但是要注意这一点很好。