Angular noobie here. I would like to know what is the best way to change the dom when a value in the scope changes by some means. I read that its not good to put the dom manipulation logic in the controller and thats the job of directives.
Here is a plunkr
http://plnkr.co/edit/xWk5UBwifbCF2raVvw81?p=preview
Basically when the data changes by clicking the load data button in the plunkr above, i want the cells whose values changed to highlight automatically. I cant get it to work for the life of me.
Any help?
I think it would be better to observer a concrete value per highlighter instead of watching the whole collection. E.g.:
<td highlighter="person.firstName">{{ person.firstName }}</td>
This way, the highlighter
-directive could be very simple, like:
app.directive('highlighter', ['$timeout', function($timeout) {
return {
restrict: 'A',
scope: {
model: '=highlighter'
},
link: function(scope, element) {
scope.$watch('model', function (nv, ov) {
if (nv !== ov) {
// apply class
element.addClass('highlight');
// auto remove after some delay
$timeout(function () {
element.removeClass('highlight');
}, 1000);
}
});
}
};
}]);
Though, for this to work you'll have to tell angular that the data actually changed. Currently this is not the case as angular tracks people
by object-identity. The moment you overwrite it, angular will remove all associated dom-elements. To accomodate for this, use:
ng-repeat="person in people track by $index"
which will tell angular to treat the index of the array as identity.
demo: http://jsbin.com/vutevifadi/1/
Thank for posting the answer above. I've noticed that the animation will flicker if value changes frequently and timeout will be fired while another animation is already active.
I've fixed this by resetting the timeout if the timeout is already set.
Also, I've added code to check if value is increasing or decreasing and set different css class.
app.directive('newvalue', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.addClass('newvalue');
scope.$watch(attrs.newvalue, function (nv, ov) {
function settimeout() {
attrs.timeout = $timeout(function () {
element.removeClass('newvalue-up');
element.removeClass('newvalue-down');
attrs.timeout = null;
}, 1000);
}
if (nv !== ov) {
if(attrs.timeout) {
//newvalue already set.. reset timeout
$timeout.cancel(attrs.timeout);
settimeout();
} else {
if(nv > ov) {
element.addClass('newvalue-up');
} else {
element.addClass('newvalue-down');
}
settimeout();
}
}
});
}
};
}]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With