Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.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 角度-检测范围的变化_Javascript_Json_Angularjs_D3.js_Angularjs Scope - Fatal编程技术网

Javascript 角度-检测范围的变化

Javascript 角度-检测范围的变化,javascript,json,angularjs,d3.js,angularjs-scope,Javascript,Json,Angularjs,D3.js,Angularjs Scope,我有一个服务可以为我获取JSON数据并将其交给控制器: 服务代码段: 控制器成功地获取了数据,我已经用控制台测试了数据。log位于$scope.d3Data=data下面行 控制器代码段: 控制器连接到一个d3 cloud指令(d3 word cloud),该指令实际上附加了适当的svg元素,并用数据绘制单词cloud但是,由于某种原因,上面的控制器没有将$scope.d3Data传递给指令。 这是令人困惑的,因为当我将一个数组中的数据硬编码到控制器中时,类似这样的事情 $scope.d3Dat

我有一个服务可以为我获取JSON数据并将其交给控制器:

服务代码段: 控制器成功地获取了数据,我已经用
控制台测试了数据。log
位于
$scope.d3Data=data下面

控制器代码段: 控制器连接到一个
d3 cloud
指令(d3 word cloud),该指令实际上附加了适当的
svg
元素,并用数据绘制单词cloud但是,由于某种原因,上面的控制器没有将
$scope.d3Data
传递给指令。

这是令人困惑的,因为当我将一个数组中的数据硬编码到控制器中时,类似这样的事情

$scope.d3Data = [
    {
        'kword': 'a',
        'count': 20,
    },{
        'kword': 'b',
        'count': 10,
    ...
。。。它完美地连接到指令

指令段: HTML代码段:


我试过什么:
  • 我试图在
    $scope.d3Data=data之后添加一个手动
    $scope.$apply()
    行。奇怪的是,在我第一次这样做时,它就起作用了,但在每次刷新页面之后,我都会收到一个“
    $digest
    已在进行中”错误(这是意料之中的…)
  • 为了修复
    $digest
    错误,我尝试将
    $apply
    函数封装在
    $timeout
    代码块中,甚至还有可怕的
    $$phase
    条件。这两种解决方案都修复了控制台错误,但未能解决将数据从控制器传递到指令的原始问题

  • TL;医生:我完全迷路了。关于下一步在何处排除故障的想法?

    似乎您将响应视为承诺两次。因此,一旦服役:

      .then(function(result) {
    
          // Resolve the promise as the data
          return result.data;
      },
    
    在控制器中,您再次解析承诺:

    requestService.getP2PKeywordData(month, year).then(function(data) {
      $scope.d3Data = data;
    });
    
    这是可行的,因为(据我理解)Angular有时会在绑定到范围时自动解析承诺

    最好只在控制器中处理承诺。因此,服务变成:

    getP2PKeywordData: function(global_m, global_y) {
    
          // Return the promise
          return $http({
                    url: base_url + 'get/P2P/kwords/', 
                    method: "GET",
    
                    // Set the proper parameters
                    params: { 
                      year: global_y,
                      month: global_m
                      }
                  });
        }
    
    更新:

    尝试将
    d3Data
    范围属性初始化为空集合,然后将响应数据推入其中。例如:

    myApp.controller('DownloadsCloudCtrl', ['$scope', 
                                            '$rootScope', 
                                            'requestService',
                                            '$cookieStore',
      function($scope, $rootScope, requestService, $cookieStore) {
    
      //added
      $scope.d3Data = [];      
    
      $rootScope.$on('updateDashboard', function(event, month, year) {
        updateDashboard(month, year);
      });
    
      var updateDashboard = function(month, year) {
        requestService.getP2PKeywordData(month, year).then(function(data) {
    
             //then
             angular.forEach(data, function(thing) {
    
                 $scope.d3Data.push(thing);
             )};
    
        });
      };
    
      updateDashboard($cookieStore.get('month'), $cookieStore.get('year'));
    }]);
    

    这是有道理的——我在服务中取消了承诺,但没有任何改变,没有新的错误,没有任何改变。我讨厌你。。。还有什么想法吗?你能展示一下你是如何在标记中的
    d3Data
    中绑定的吗?添加了HTML!谢谢你。这是在黑暗中拍摄的,但是也许你应该在控制器中初始化一个空的集合,然后将结果数据推送到其中。然后该指令的对象引用将保持不变。抱歉,我正在移动中,现在不能。希望我至少帮了点忙。
      .then(function(result) {
    
          // Resolve the promise as the data
          return result.data;
      },
    
    requestService.getP2PKeywordData(month, year).then(function(data) {
      $scope.d3Data = data;
    });
    
    getP2PKeywordData: function(global_m, global_y) {
    
          // Return the promise
          return $http({
                    url: base_url + 'get/P2P/kwords/', 
                    method: "GET",
    
                    // Set the proper parameters
                    params: { 
                      year: global_y,
                      month: global_m
                      }
                  });
        }
    
    myApp.controller('DownloadsCloudCtrl', ['$scope', 
                                            '$rootScope', 
                                            'requestService',
                                            '$cookieStore',
      function($scope, $rootScope, requestService, $cookieStore) {
    
      //added
      $scope.d3Data = [];      
    
      $rootScope.$on('updateDashboard', function(event, month, year) {
        updateDashboard(month, year);
      });
    
      var updateDashboard = function(month, year) {
        requestService.getP2PKeywordData(month, year).then(function(data) {
    
             //then
             angular.forEach(data, function(thing) {
    
                 $scope.d3Data.push(thing);
             )};
    
        });
      };
    
      updateDashboard($cookieStore.get('month'), $cookieStore.get('year'));
    }]);