Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度引导-使用引导工具提示反复调用$compile会导致速度缓慢_Javascript_Angularjs_D3.js_Angular Ui Bootstrap - Fatal编程技术网

Javascript 角度引导-使用引导工具提示反复调用$compile会导致速度缓慢

Javascript 角度引导-使用引导工具提示反复调用$compile会导致速度缓慢,javascript,angularjs,d3.js,angular-ui-bootstrap,Javascript,Angularjs,D3.js,Angular Ui Bootstrap,我有一个应用程序使用每秒轮询一次来更新饼图指令。我使用d3绘制饼图,我想在饼图上使用引导工具提示。为了实现这一点,我使用angular bootstrap,并在每次数据更新时手动调用$compile来处理tooltip指令。看起来是这样的: app.directive('piechart', ['$compile', function($compile) { return { restrict: 'E', scope: { data: '=', w: '=widt

我有一个应用程序使用每秒轮询一次来更新饼图指令。我使用d3绘制饼图,我想在饼图上使用引导工具提示。为了实现这一点,我使用angular bootstrap,并在每次数据更新时手动调用$compile来处理tooltip指令。看起来是这样的:

app.directive('piechart', ['$compile', function($compile) {
    return {
      restrict: 'E',
      scope: { data: '=', w: '=width', h: '=height', label: '=' },
      link: function(scope, element) {

        ...

        var svg = d3.select(element[0])
              .append('svg')
                .attr('width', scope.w)
                .attr('height', scope.h);

        scope.$watch('data', function(newValue) {

          if (newValue) {

            var pieData = pie(newValue);

            var arcs = svg.selectAll('g.arc')
              .data(pieData, function(d) { return d.data.label; });

            arcs.attr('tooltip', function(d, i) { 
                  return scope.data[i].label + ': ' + scope.data[i].value; 
                }).select('path')
                .transition()
                .delay(100)
                .duration(750)
                .attrTween('d', arcTween);

            var enteredArcs = arcs.enter()
              .append('g')
                .attr('class', 'arc')
                .attr('transform', 'translate(' + outerRadius + ',' + outerRadius + ')')
                .attr('tooltip-append-to-body', true)
                .attr('tooltip', function(d, i) { 
                  return scope.data[i].label + ': ' + scope.data[i].value; 
                });

            enteredArcs.append('path')
                .attr('fill', 'white')
                .attr('stroke', 'white')
                .attr('stroke-width', 2)
                .on('mouseover', function() { d3.select(this).transition().duration(500).attr('d', arcOver); }) 
                .on('mouseout', function() { d3.select(this).transition().duration(200).attr('d', arc); })
                .each(function(d) { this._current = d; }) // store the initial angles
                .transition()
                .delay(function(d, i) { return (i * 20) + 50; })
                .attr('fill', function(d) { return color(d.data.label); })
                .attr('d', arc);             

            arcs.exit().remove();

            $compile(svg[0])(scope);
          }
        }, true);
      }
    };
}]);
我注意到,在运行一分钟左右后,它变得异常缓慢,反应迟钝。如果我在元素上移动鼠标时进行轮廓分析,我会发现它在
$interpolate.fn
中花费了大量的时间。根据探查器,调用堆栈是:

hideTooltipBind->Scope.$apply->Scope.$digest->$interpolate.fn

(其中hideTooltipBind位于ui引导tpls.js中)

我猜在对$compile的重复调用中,旧的工具提示没有被清理?这是angular bootstrap中的错误还是我的代码中的问题


Edit:似乎在重复调用$compile时,第一次调用$compile创建的子作用域没有被销毁,而$destroy是注销工具提示绑定的部分。不确定如何销毁旧的子上下文。

我通过在调用$compile之前手动销毁指令作用域的所有子作用域来解决这个问题。由于该指令使用隔离作用域,因此应该是安全的。如果有人有更好的主意,我很乐意听

代码:

var destroyer = function(scopeElem) {
  if(scopeElem.$$nextSibling) {
    destroyer(scopeElem.$$nextSibling);
  }
  scopeElem.$destroy();
};

if(scope.$$childHead) {
  destroyer(scope.$$childHead);
}

$compile(svg[0])(scope);