3

Struggling for a good example of this.

I'm want to have a chart directive that will be updated every minute by polling a web service.

I currently have a service which is a wrapper for my web service. My controller can access this service and populate templates successfully. I have also created a chart directive which can display static data. I now want to make it possible for real time updating of this chart directive and potentially multiple charts on the same page. Should the polling logic therefore be inside the directive? I want every chart to be able to poll at different intervals.

A simplified example would of course be appreciated.

EDIT FROM COMMENT:

I would prefer to be able to add my directive like so:

<chart pollingperiod="12" param1="somevalue" param2="somevalue"></chart> 

I think this would mean my directive would have to take the responsibility of the polling, or somehow pass these parameters to the controller to set up the polling.

JMac
  • 523
  • 1
  • 5
  • 17
  • 1
    This is what I've done: http://stackoverflow.com/questions/14237070/using-setinterval-in-angularjs-factory/14238039#14238039 – Sharondio Jul 24 '13 at 14:17
  • Not sure what your backend is, but if it's .NET, you may want to take a look at SignalR @ https://github.com/SignalR/SignalR – Mike Pugh Jul 24 '13 at 18:29
  • Signalr is definitely an option but at the moment I'm just looking for a more naive polling approach as I'm getting to grips with Angular. I'd probably prefer my backend to be totally decoupled though, providing all data through a REST API. – JMac Jul 25 '13 at 08:03
  • Thanks @Sharondio, that definitely helped me get going. – JMac Jul 25 '13 at 12:36

2 Answers2

5

I have written this example : http://jsfiddle.net/rishabh/Kuewm/

You can have 2 way data-binding using '=' in directive scope when declaring hash.

scope : {
          value : '='  // '=' indicates 2 way binding
        }

Now you need to update the data in your controller for each chart independently and they will get updated in your view/directive.

Now you can poll your service using $timeout like this :-

$scope.chartValue = /*service call to init */;
var poll = function() {
   $timeout(function() {
      /* service call to update chartValue */
      poll();
   }, 1000);
};     
poll();

This will update your chartValue after 1000 millisec. You can use different values for different charts.

Edit : This is the fiddle http://jsfiddle.net/rishabh/76sKy/

You can just pass the value and have them updated in controller of directive.

scope : {
            pollingperiod : '@',
            param1 : '@',
            param2 : '@'
        },
controller: ['$scope', '$element', '$attrs', '$transclude', '$timeout', 
             function($scope, $element, $attrs, $transclude, $timeout) {
                 var poll = function() {
                     $timeout(function() {
                         //update your chart
                         $scope.param1 = $scope.param2;
                         $scope.param2++ ;
                         poll();
                     }, 100*$scope.pollingperiod);
                 };     
                 poll();}],
Rishabh Singhal
  • 1,173
  • 10
  • 22
  • I'm not sure about this approach. It means for every new chart I would have to add a new section to the controller if I wanted different polling periods for instance. I would prefer to be able to add my directive like so: I think this would mean my directive would have to take the responsibility of the polling, or somehow pass these parameters to the controller to set up the polling. – JMac Jul 25 '13 at 08:06
  • @JMac : I have edited the answer and edit contains what you were looking for. Only downside to this approach is you can't update different charts using different logic. – Rishabh Singhal Jul 25 '13 at 12:06
  • Thanks. I'll accept as answer. I had just come back on to say I'd got it in a pretty much identical manner. – JMac Jul 25 '13 at 12:35
0

Here's a very hacked together version of where I got to:

    link: function($scope, element, attrs, controller){

        var count= 0;

        function updateChartData() {

        var poll = $timeout(function myFunction() {

                count++;
                $scope.output = "" + $scope.poll + ", " + count + ": " + Math.random();
                $scope.$apply();

                updateChartData();

        }, $scope.poll * 1000); //timeout in milliseconds

        $scope.$on('$destroy', function(e) { $timeout.cancel(poll); });
        };

        updateChartData();
    },

    scope: {
        title: "@",
        poll: "@"
    } 
}
JMac
  • 523
  • 1
  • 5
  • 17