繁体   English   中英

角度检测范围的变化

[英]Angular- detecting a change in scope

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

服务片段:

...
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
                  }
              })
              .then(function(result) {

                  // Resolve the promise as the data
                  return result.data;
              },
              function(data) {
                  // Error handling
              });
    }
    ...

控制器成功获取了数据,我已经在$scope.d3Data = data;下面用console.log测试了这些$scope.d3Data = data; 线。

控制器代码段:

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'));
}]);

控制器已连接到d3-cloud指令(d3词云),该指令实际上附加了适当的svg元素并使用数据绘制词云。 但是,由于某些原因,上述控制器没有将$scope.d3Data传递给指令。

这是令人困惑的,因为当我将数据数组中的硬编码到控制器中时,就像这样...

$scope.d3Data = [
    {
        'kword': 'a',
        'count': 20,
    },{
        'kword': 'b',
        'count': 10,
    ...

...它完美地连接到指令!

指令段:

myApp.directive('d3Cloud', ['$window', 
                            'd3Service', 
                            'd3Cloud', 
                            function($window, 
                                     d3Service, 
                                     d3Cloud) {
  return {
    restrict: 'EA',
    scope: {
      data: '=',
      label: '@'
    },
    link: function(scope, element, attrs) {
      d3Service.d3().then(function(d3) {
        window.onresize = function() {
          scope.$apply();
        };
        scope.$watch(function() {
          return angular.element($window)[0].innerWidth;
        }, function() {
          scope.render(scope.data);
        });
        scope.render = function(data) {

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>

我尝试了什么:

  1. 我试图在$scope.d3Data = data;之后添加一个手动$scope.$apply() $scope.d3Data = data; 控制器中的线路。 奇怪的是,这是我第一次这样做的方法,但是此后在刷新每个页面时,我都遇到了“ $digest已经进行中”错误(这是预料之中的...)。
  2. 为了解决$digest错误,我尝试将$apply函数封装在$timeout代码块中,甚至将可怕的$$phase条件封装起来。 这两种解决方案都解决了控制台错误,但是未能解决将数据从控制器传递到指令的原始问题。

TL; DR:我很迷茫。 关于下一步如何排除故障的想法?

看来您将响应视为承诺两次。 因此,一旦服务:

  .then(function(result) {

      // Resolve the promise as the data
      return result.data;
  },

然后在控制器中再次解决承诺:

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

之所以可行,是因为(据我了解)Angular有时在绑定到合并范围时会自动解析promise。

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

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'));
}]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM