AngularJS Trigger ng-animate when binding value change

I ran into a similar problem when trying to highlight text during a data bind. My goal is to highlight the text that is being changed for a sleeker UI. From a UI perspective this ensures that the user knows what is being changed while they fill out a form.

Here's what I learned (I attached a fiddle below)

First, you do not want to use watch. This will create an unpleasant cycle of true::false on ng-class and hence will not output a clean transition.

Second, you cannot think of angular as jquery where you find an element and change it. The key to angular is reusability, which my initial attempts severely lacked.

Third, events such as ng-focus, ng-blur, ng-click, (... and many more), are the bread and butter in getting the results I wanted.

My solution is to use ng-focus and ng-blur to detect when an input was being edited

<input ng-focus="highlight('name')" ng-blur="doneHighlight('name')" 
ng-model="user.name" />

During ng-focus I am calling a highlight function and passing through an argument called 'name'. This argument is key to reusability.

 $scope.highlight = function(className){
    $scope.toggle = className;
}

Once passed through, toggle equals the argument.

Here's the kicker...

<div  ng-class="{'toggle': toggle=='name', 'noToggle': toggle=='name'+false}">
    {{user.name}}
</div>

When toggle is == to the passed argument then highlight is applied when it is == to 'name'+false the 'noToggle' class is applied with the smooth unhighlight animation.

Wait... what about ng-blur? I am glad you asked! ng-blur calls a 'doneHighlight' function and passes the same class argument.

$scope.doneHighlight = function(className){
    $scope.toggle = className + false;
}

However, when passing the argument it also attaches a false value at the end of the classname. This is a different mindset then jQuery but allows me to reuse the functions in the controller for as many elements as necessary;

Hope this helped! I am happy to answer any further questions.

http://jsfiddle.net/bebold/8MAKT/1


I think there's a better way that involves no new JS code other than including ngAnimate.

Take this example:

<span class="my-example value-{{myValue}}">{{myValue}}</span>

By setting a class that uses the value, I can uses ngAnimate abilities for class changes.

In my SCSS (or LESS) I would write:

span.my-example{
    display: inline-block;
    padding: 0 3px;
    background-color: white;
    transition: background-color 0.26s linear 0s;
    &[class*="-add"] {
        background-color: yellow;
    }
}

And voila! The background colour would change to yellow and back every time the value changes as ngAnimate automatically adds and removes classes like 'value-2-add', 'value-10-add', etc...


In angular 1.2.0 you can use a directive that watches for content changes and adds then removes the classes. You can tie an animation to those class adds and removes that triggers the fading effect you are looking for.

module.directive('contentChange', function(){

 return {

  scope: {
   content: '='
  },

  template: '<span ng-bind-html="myContent"></span>',

  link: function(scope, element, attrs){
   scope.$watch('content', function(){

    //add fader class to element

    scope.myContent = content;

    //remove fader class from element
   });
  };
 } //return
});

Here's a popular article on 1.2 animations: http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html