title: How can I create an AngularJS directive to animate an element on data change?
body: <p>In the app I'm building I have a headline that shows on the screen. It's bound to a property in my scope. I'm using <code>ng-bind-html</code> to ease the way I'm building the headline string. The HTML looks something like this:</p>
  
  <pre><code>&lt;div class="headline slide-and-fade-up" animate-on-change="headline" ng-bind-html="headline"&gt;&lt;/div&gt;
  </code></pre>
  
  <p><code>animate-change</code> is a directive I'm trying to write that will cause the headline to animate when it changed. The requested animation is for the old animation to move up and off the screen while the new one moves up from the bottom and into place. I've built an animation that is compatible with <code>ng-animate</code> called <code>slide-and-fade-up</code> that does what I want it to do. Since I need to animate the old value leaving as the new one comes on, I need to duplicate the element and have one with the old value and one with the new both in the DOM and then have the old one leave.</p>
  
  <p>So far, my directive looks like this:</p>
  
  <pre><code>angular.module('myApp.directives').directive('animateOnChange', ['$animate',
      function($animate) {
          return {
              restrict: 'A',
              link: function(scope, element, attrs) {
                  scope.$watch(attrs.animateOnChange, function(newValue, oldValue) {
                      if (newValue !== undefined &amp;&amp; oldValue !== undefined &amp;&amp; newValue !== oldValue) {
                          $animate.enter(element.clone(), element.parent(), element);
                          $animate.leave(element);
                      }
                  });
              }
          }
      }
  ]);
  </code></pre>
  
  <p>This has a couple of problems:</p>
  
  <ol>
  <li>The cloned element does not seem to have a "live" directive on it, i.e. it exists in the DOM but doesn't actually fire this code which means the animation fires exactly once then never again</li>
  <li>The element that enters has the old value in it and the enter that leaves has the new value in it. I have no idea why this would be the case but it's basically exactly backward</li>
  </ol>
  
  <p>How can I finish this directive to get it to do what I want? I did get it to work by using an <code>ng-if</code> and watching for a data change and toggling a boolean on, waiting a short time and then toggling it back on. That worked, but seemed overly hacky to me compared to a self contained directive with <code>$animate</code> hooks. Thanks for the help.</p>