【问题标题】:AngularJS add jQuery dom eventlisteners after ng-repeatAngularJS 在 ng-repeat 之后添加 jQuery dom 事件监听器
【发布时间】:2014-06-04 10:40:34
【问题描述】:

我正在将带有图表的基于 D3 的网站迁移到 Angular。每个单独的图表仍将由 D3 绘制,但每个图表都将在管理图表的角度 directive 上。

其中一个图表元素由图表 (SVG) 和作为其图例的 HTML 表格组成。

[ svg (chart) ][ table (legend) ]

D3 绘制图表,我使用ng-repeat 绘制图例。在这种情况下,图例和图表都需要交互:需要有 DOM 事件监听器。然而,指令的控制器在 ng-repeat 绘制图例之前运行(因此 DOM 元素还不存在)。

查看:

<div ng-transclude></div>
<div class="wrapper">
    <svg></svg>
    <div class="valign">
        <table>
            <tr>
                <th>#</th>
                <th>Name</th>
                <th>BTC</th>
                <th>USD</th>
            </tr>
            <tr ng-repeat="item in items" class="legend item-{{item.title}}" title="{{item.title}}">
                <th>{{$index + 1}}</th>
                <td>{{item.title}}</td>
                <td>{{item.btc | bitcoin}}</td>
                <td>{{item.usd | currency}}</td>
            </tr>
        </table>
    </div>
</div>

指令:

angular
  .module('d3.charts', [])
  .directive('volumeElement', function() {
    return {
      restrict: 'E',
      scope: {
        data: '='
      },
      transclude: true,
      link: function(scope, element, attrs) {

        // todo: this needs to be changed upstream in the volume controller
        scope.mode = '24h';

        // the d3 chart function
        var chart = new window.WZB.VolumeChart(
          element.find('svg')[0],
          scope.data
        );

        var $paths, $legend;

        var render = function() {
          chart.mode = scope.mode;
          chart.render();

          $paths = element.find('.interactive');

          addHovers();
        }

        var addHovers = function() { 
          // PROBLEM: at this point the ng-repeat has not populated the legend yet
          $legend = element.find('.legend')
          $paths.hover(function(e) {
            var $path = $(e.target);
            var title = $path.attr('title');

            var legend = $legend
              .filter(function() {
                var nonActive = $(this).attr('title') !== title;

                if(!nonActive)
                  $(this).removeClass('blur')

                return nonActive;
              })

              $paths
                .not($path)
                .add(legend)
                .addClass('blur');
            }, function() {
              $paths.add($legend)
                .removeClass('blur');
            })
        }

        render();
      },
      templateUrl: '/volume-element.html'
    }
  })

我将 jQuery 用于更高级的 DOM 操作,我不能只依赖 angular 的 ng-mouseover 指令,因为我需要 angular 生成的表和 D3 生成的 SVG 的事件侦听器。

如何在ng-repeat 填充图例后立即执行代码?


黑客解决方案:

// todo: proper fix
// see @link https://stackoverflow.com/questions/24035289/angularjs-add-jquery-dom-eventlisteners-after-ng-repeat
setTimeout(addHovers, 0);

【问题讨论】:

    标签: javascript jquery angularjs d3.js


    【解决方案1】:

    我已经重构了代码,我并没有以角度的方式思考。包含新指令并且 d3 还创建表,而不是混合 angular 和 d3 以获得相同的可视化。这样我就不再需要jQuery了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-13
      • 2012-05-17
      • 1970-01-01
      • 2014-05-11
      相关资源
      最近更新 更多