javascriptangularjsangularjs-directiveangularjs-ng-repeatng-animate

How to use ng-enter & leave css animations inside of directive


I have an ng-repeat element inside of an angular directive that I would like to animate.

Now, I've already added the angular-animate file to the document & ngAnimate dependency to my app... the element however, doesn't seem to be getting the ng-* animation classes applied to it. I thought the ng-repeat directive was automatically aware of ngAnimate? what am I missing? does placing it inside of a directive somehow force me to use $animate directly?

http://plnkr.co/edit/VOVUtq1BZjop2LBWDk8a?p=preview

index.html

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script data-require="angular.js@1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
    <script data-require="angular-animate@1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-animate.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <alerts></alerts>
  </body>

</html>

script.js

'use strict';

var app = angular.module('app', ['ngAnimate']);

app.run(function(alert) {
  alert.success('Hello World!');
});

app.factory('alert', function($timeout) {

  var options = {
    duration: 3000
  };

  var counter = 0;

  var alerts = [];

  function createAlert(type, message) {
    var alert = {
      type: type, message: message, id: counter++
    };

    alert.promise = $timeout(function() {
      removeAlert(alert.id);
    }, options.duration);

    alerts.push(alert);
  }

  function removeAlert(id) {
    var alert = find(id);
    if (alert && !alert.deleting) {
      alert.deleting = true;
      var index = alerts.indexOf(alert);
      // Cancel the automatic timeout
      $timeout.cancel(alerts[index].promise);
      // Remove from the alerts array
      alerts.splice(index, 1);
    }
  }

  function clear(alert) {
    if (alert) {
      removeAlert(alert.id);
    } else {
      for (var i = 0; i < alerts.length; i++) {
        removeAlert(alerts[i].id);
      }
    }
  }
  function find(id) {
    for (var i = 0; i < alerts.length; i++) {
      if (alerts[i].id === id) {
        return alerts[i];
      }
    }
  }

  function success(message) {
    createAlert('success', message);
  }

  return {
    alerts: alerts,
    success: success,
    clear: clear
  }
});

app.directive('alerts', function(alert) {
  return {
    restrict: 'AE',
    templateUrl: 'alerts.html',
    scope: true,
    controller: function($scope) {
      $scope.close = function(a) {
        alert.clear(a);
      };
    },
    link: function(scope) {
      scope.alerts = alert.alerts;
    }
  }
});

alerts.html

<div ng-repeat="alert in alerts" class="alert alert-{{alert.type}}">
  <button type="button" class="close" ng-click="close(alert)">&times;</button>
  {{alert.message}}
</div>

style.css

.ng-leave {
  transition: all 1s linear;
}

.ng-leave {
  opacity: 1;
}

.ng-leave-active {
  opacity: 0;
}

Solution

  • Oh. You didn't import style.css!