3

I'm trying to create an app where I poll live data every 10 seconds or so. And if the data changes it should get highlighted in the view. I have successfully managed this, but with a little help from jQuery. I want to do it with a template in angular instead.

This is my controller:

angular.module('myApp.controllers', [])
.controller('MainCtrl', ['$rootScope', 'liveDataPoller', function($rootScope, liveDataPoller) {
    $rootScope.liveData = liveDataPoller.getData();
}]);

This is my directive:

angular.module('myApp.directives', []).
directive('liveValue', function() {
    return {
        restrict: 'A',
        scope: {
            val: '='
        },
        link: function(scope, element, attrs) {
            scope.$watch('val', function(newValue, oldValue) {
                if(newValue && oldValue && (newValue !== oldValue)) {
                    if(newValue < oldValue) {
                        element.removeClass("up").addClass("down");
                    } else {
                        element.removeClass("down").addClass("up");
                    }
                } else {
                    element.removeClass("down").removeClass("up");
                }
            });
        }
    }
});

This is my view:

<div live-value val="liveData.randomInteger">{{liveData.randomInteger}}</div>

Is it possible to have the add/remove class changed to use transclude and a template instead? Don't really want to mix jQuery in this.

Just let me know if anything is unclear.

KungWaz
  • 1,918
  • 3
  • 36
  • 61
  • 1
    Do you want the HTML you are showing to be a directive template? Both `addClass` and `removeClass` are included in jqLite, which is included in Angular, so you don't need jQuery to use them. – tasseKATT Jun 02 '14 at 15:43
  • Ok, that is probably true and I didn't know that. But still, want to learn Angular better. Got any ideas, can I get a binding between a link and a template in a directive, feks. an ng-switch to change the class or something like that? – KungWaz Jun 02 '14 at 15:45

1 Answers1

1

Sample demo: http://plnkr.co/edit/uXhOceXYWLLkmRkzxx1h?p=preview

A scope variable can be used to track the new changes and use a two way binding to update the class in the html.

app.directive('liveValue', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      data: '=', change:'='
    },
    template: '<div class="{{change}}">The value({{data}}) has gone: {{change}}</div>',
    link: function(scope, element, attrs) {
      scope.change = '';
      scope.$watch('data', function (newValue, oldValue) {
        if (newValue == oldValue) {
          scope.change='nochange';
        }else if(newValue<oldValue){
          scope.change='down';
        }else{
          scope.change='up';
        }
      });
    }
  }
});
guru
  • 4,002
  • 1
  • 28
  • 33
  • Thanks! It totally works :) Now to the important question. Is this a good approach from an architectural point of view, if you have an ng-repeat with many elements that will change every 10 seconds and want to watch them? – KungWaz Jun 02 '14 at 16:16
  • @tasseKATT i had forked yours, changed a few things and it wasnt saved :) and yes +1 for your answer. regarding performance there is already an good answer on this. Please have a look at this - http://stackoverflow.com/a/9693933/897273 – guru Jun 02 '14 at 17:15