ng-repeat完成后触发D3重绘

时间:2014-04-21 14:55:42

标签: arrays angularjs d3.js angularjs-ng-repeat redraw

关于使用AngularJS和D3的应用程序,我有一个有趣的问题。基本上,我有一个ng-repeat,它根据数组的内容重复。在这个数组中是包含REST URL的对象,它们会定期到达并从中提取数据。获得此数据后,将使用D3绘制图形(阵列中每个对象的一个​​图形)。

我遇到的问题是通过用户输入动态地将对象添加到此数组,并使绘图正常工作。似乎d3代码跳过枪并开始尝试选择尚未渲染的SVG元素,因为Angular仍在通过ng-repeat完成向DOM添加内容。

我尝试过使用$ timeout,并且还创建了一个类似于此的自定义指令:ng-repeat finish event

它运行良好,但似乎只是在第一次运行ng-repeat时触发事件,而不是在我向阵列添加另一个对象时。有关处理这种情况的最佳方法的任何评论?如果我可以在每次添加/删除新对象时基于$ last触发事件,然后遍历数组并调用绘图函数,这似乎可以工作。

干杯!

编辑:D3代码目前与此http://bl.ocks.org/mbostock/1346410类似,这只是一个简单的圆环图更新,但需要注意的是重绘是由REST调用触发的。然而,将来可能会有更复杂的图表,这就是我希望使用D3的原因。

编辑2:我已经将我的所有D3代码都移动到了一个自定义指令中,经过大量的乱码后,它几乎可以正常工作。通过不隔离范围,自定义元素具有与ng-repeat相同的范围,并且可以访问对象及其属性,以及相关的DOM元素(当前我正在创建具有每个对象唯一的ID的DIV )。

当使用d3.select时出现问题...当我尝试选择我要放置绘图的DIV时,它不允许我按ID选择,因为它返回null ..这很奇怪关于这个,如果我选择所有(“div”),它可以找到我正在寻找的div,但不会让我选择那个。

这是一个显示我的意思的JsFiddle ...检查控制台并看到第一个测试返回div“obj1”,但第二个选择返回null。

如果我可以让这个工作,然后附加我的SVG画布并在该div中绘图,我认为它会起作用!

相关选择:

    var test = d3.selectAll("div");
       console.log(test);
       var chart = d3.select("#obj" +obj.id);
       console.log(chart);

应该创建div的HTML:

    <div ng-repeat="object in myData">
        <div id="obj{{object.id}}">
            Hi 
           <bars-chart></bars-chart>
       </div>
   </div> 

http://jsfiddle.net/SleepyProgrammer/eN6p7/3/

1 个答案:

答案 0 :(得分:3)

根本不需要使用ID进行选择。您只需选择传入Angular指令element[0]函数的link

var chart = d3.select(element[0]).append('svg')

例如:

angular.module('myApp', []).
   directive('barsChart', function () {
     return {
         restrict: 'E',
         link: function (scope, element, attrs) {
             var chart = d3.select(element[0]).append('svg').attr({height: 20, width: 20});             
             chart.append('rect').attr({height: 10, width: 10});             
         } 
      };
   });

function Ctrl($scope, $timeout) {
    $scope.myData = [ {"id":"1"}, {"id":"2"}];

    // just to show that it reacts to changes in the data and will render more SVGs
    $timeout(function() {
        $scope.myData.push({"id":"3"});
    }, 3000);    
}

请参阅JSFiddle:

http://jsfiddle.net/4vdvq/2/