单个控制器

时间:2016-08-09 14:09:17

标签: javascript angularjs highcharts

我正在构建一个使用Highcharts可视化某些数据的网页。 为了使其可重用,我在指令

中包装了我想要的图表
'use strict';
angular.module('statisticsApp')
  .directive('cleanbarchart', function () {
    scope:{
      localdata:'@'
    }
    return {
      template: '<div></div>',
      restrict: 'E',
      link: function postLink(scope, element, iAttrs) {
          // console.log(iAttrs);
          // console.log(iAttrs);
          // var attrs = JSON.parse(iAttrs.id);
          var attrs = iAttrs;
          element.highcharts({
            chart: {
              type: 'column',
              width:1000,
              zoomType: 'x'
            },
            title: {
              text: scope.localdata[attrs.id].title //title
            },
            xAxis: {
              categories: scope.localdata[attrs.id].categories, crosshair: true

            },
            yAxis: {
              min: 0
            },
            tooltip: {
  //            headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
  //            pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
  //            '<td style="padding:0"><b>{point.y:.1f} mm</b></td></tr>',
  //            footerFormat: '</table>',
  //            shared: true,
  //            useHTML: true
            },
            plotOptions: {
  //            column: {
  //            pointPadding: 0.2,
  //            borderWidth: 0
  //          }
            },

            series: scope.localdata[attrs.id].series
          })
      }
    };
  });

在我的控制器中,我使用服务和回调函数来填充localdata

angular.module('statisticsApp')
  .controller('AboutCtrl', function ($scope, HttpDataService) {

     function done(data){

       console.log(data);
       $scope.localdata['test2'] = data; //HttpDataService.getUniqueUsers() ;
     }

     $scope.localdata = {} ;
     HttpDataService.getUniqueUsers(done) ;
});

使用如下服务:

angular.module('statisticsApp')
  .service('HttpDataService', function($http, $q, baseRestPath) {
    // AngularJS will instantiate a singleton by calling "new" on this function
    return {
      getUniqueUsers: function (callback, periodicity) {
        var url = baseRestPath + '/sessions/uniqueUsers';
        console.log(url);
        var dates = [];
        var values = [];

        $http.get(url).then(
          function successCallback(response){
            var data = response.data;
            data.forEach(function(dataLine) {
              dates.push(dataLine[1]);
              values.push(dataLine[0]);
            })
            console.log(values);
            callback({title: 'Unique Users', categories:dates, 'series': [ {name: 'Alltime', data:values} ]  });
        //    return {'title': "Unique Users", 'categories':dates, 'series': [ {name: "Alltime", data:values} ]  }
          },function errorCallBack(response){
            //do nothing
          }
        );


//      return {'title': "Unique Users", 'categories':dates, 'series': [ {name: "Alltime", data:values} ]  }
      }
    }
  });

最后,在我的html中,我使用以下代码来调用指令

<cleanbarchart id="test2"></cleanbarchart>

虽然我确定我的服务正常,并正确返回数据,但我收到了错误

  

无法读取未定义的属性'title'

我认为它与$ http工作的异步方式有关,但我无法弄清楚如何在scope.localdata或scope.localdata [attrs.id]上制作指令,我试过将element.highcharts包装在监视块中

link: function postLink(scope, element, iAttrs) {
  scope.$watch('localdata',function(){
    element.highcharts.....
  }
}

or 

link: function postLink(scope, element, iAttrs) {
  scope.$watch('localdata[' + attrs.id + ']',function(){
    element.highcharts.....
  }
}

所有帮助表示赞赏

1 个答案:

答案 0 :(得分:2)

首先,您需要更改服务以返回承诺,而不是将回调传递给您的服务。如果您打开$http documentation,您会看到$http.get返回HttpPromise对象,稍后您可以解析该对象。

完成后,您可以将promise传递给指令而不是数据。

所以而不是:

$scope.localdata = {} ;
HttpDataService.getUniqueUsers(done) ;

更改为:

$scope.localdataPromise = HttpDataService.getUniqueUsers();

后来在指令中解决了这个问题:

scope.localdataPromise.then(function (data) { /* resolve data and draw chart */ });