简体   繁体   English

单个控制器中的多个角度相同的指令

[英]angular multiple same directives in single controller

I'm building a webpage that uses Highcharts to visualize some data. 我正在建立一个使用Highcharts可视化某些数据的网页。 To make it reusable, I've wrapped the chart that I want in a directive 为了使其可重用,我将所需的图表包装在指令中

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

In my controller, I use a service and a callback function to populate the 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) ;
});

with a service that looks like this: 提供的服务如下所示:

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

and finally, in my html i use the following code to call the directive 最后,在我的html中,我使用以下代码调用指令

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

while I'm certain that my service works, and returns the data correctly, I get the error 虽然我确定我的服务可以正常工作,并且可以正确返回数据,但是却收到了错误消息

Cannot read property 'title' of undefined 无法读取未定义的属性“标题”

I think it has to do with the asynchronous way that $http works, but I can't figure out how to make the directive watch on either scope.localdata or scope.localdata[attrs.id] which I have tried by wrapping the element.highcharts in the watch block 我认为这与$ http工作的异步方式有关,但我无法弄清楚如何通过包装该元素尝试在scope.localdata或scope.localdata [attrs.id]上进行指令监视手表块中的.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.....
  }
}

All help appreciated 所有帮助表示赞赏

Firsty you need to change your service to return a promise instead of passing a callback to your service. 首先,您需要更改服务以返回承诺,而不是将回调传递给服务。 If you open $http documentation you will see that $http.get returns HttpPromise object which you can later resolve. 如果打开$http 文档,您将看到$http.get返回HttpPromise对象,您以后可以解析该对象。

After you done that you can pass promise to directive instead of data. 完成之后,您可以将promise传递给指令而不是数据。

So instead of: 所以代替:

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

Change to: 改成:

$scope.localdataPromise = HttpDataService.getUniqueUsers();

And later in directive resolve it like that: 然后在指令中像这样解决它:

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

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

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