我有一个链接到d3-cloud指令且完美运行的控制器(下面的代码)。数据被添加到控制器中并传递给指令。

myApp.controller('DownloadsCloudCtrl', ['$scope',
                                        '$rootScope',
                                        'requestService',
                                        '$cookieStore',
  function($scope, $rootScope, requestService, $cookieStore){
  $scope.d3Data = [
    {
        'kword': 'a',
        'count': 141658,
    },{
        'kword': 'b',
        'count': 105465,
    }
  ];
}]);


现在,我试图通过将控制器切换到以下代码来从JSON请求服务中提取数据。当我在console.log行下面的控制器中执行$scope.d3Data = data时,一切似乎都正常工作(返回了正确的数据)。

但是,尝试将控制器链接到指令时,由于某些原因,指令获取的是未定义/空数据集,所以某些操作会中断。

我想知道问题是否在代码执行的顺序上。也许控制器尝试在JSON服务完成之前将数据传递给指令,从而导致未绘制任何图形。这可能发生吗,如果是这样,我该如何解决呢?

myApp.controller('DownloadsCloudCtrl', ['$scope',
                                        '$rootScope',
                                        'requestService',
                                        '$cookieStore',
  function($scope, $rootScope, requestService, $cookieStore){
  $rootScope.$on('updateDashboard', function(event, month, year) {
    updateDashboard(month, year);
  });

  var updateDashboard = function(month, year) {
    requestService.getP2PKeywordData(month, year).then(function(data) {
      $scope.d3Data = data;
    });
  };

  updateDashboard($cookieStore.get('month'), $cookieStore.get('year'));
}]);


编辑:指令代码:

myApp.directive('d3Cloud', ['$window',
                            'd3Service',
                            'd3Cloud',
                            function($window,
                                     d3Service,
                                     d3Cloud) {
  return {

    // Restrict usage to element/attribute
    restrict: 'EA',

    // Manage scope properties
    scope: {

      // Bi-directional data binding
      data: '=',

      // Bind to DOM attribute
      label: '@'
    },

    // Link to DOM
    link: function(scope, element, attrs) {

      // Load d3 service
      d3Service.d3().then(function(d3) {

        // Re-render on window resize
        window.onresize = function() {
          scope.$apply();
        };

        // Call render function on window resize
        scope.$watch(function() {
          return angular.element($window)[0].innerWidth;
        }, function() {
          scope.render(scope.data);
        });

        // Render d3 chart
        scope.render = function(data) {

        // d3 specific appends... not important


HTML代码:(足够简单)

  <div class="col-md-6">
    <div class="module">
      <div class="inner-module" ng-controller="DownloadsCloudCtrl">
        <div class="module-graph">
          <d3-cloud data="d3Data"></d3-cloud>
        </div>
      </div>
    </div>
  </div>

最佳答案

尝试在$ scope.d3Data = data之后添加$ scope。$ apply();

$scope.d3Data = data;
$scope.$apply();


如果这不起作用,则始终可以将函数向下传递给指令,并将其设置为更新数据,然后从控制器手动调用它:

所以控制器逻辑:

$scope.updateDirective = function () {}; // this will be overridden in directive


指令逻辑:

scope: {
  data: '=',
  update: '&updateDirective'
  label: '@'
}

scope.updateDirective = function () {
  scope.render(scope.data); // call to update function
};


标记:

  <div class="col-md-6">
    <div class="module">
      <div class="inner-module" ng-controller="DownloadsCloudCtrl">
        <div class="module-graph">
          <d3-cloud data="d3Data" update-directive="updateDirective"></d3-cloud>
        </div>
      </div>
    </div>
  </div>

08-18 13:08
查看更多