AngularJS Example

HTML

<div ng-app="App" ng-controller="myC">
  <div ng-init="friends = [
    {name:'John', age:25, gender:'boy'},
    {name:'Jessie', age:30, gender:'girl'},
    {name:'Johanna', age:28, gender:'girl'},
    {name:'Joy', age:15, gender:'girl'},
    {name:'Mary', age:28, gender:'girl'},
    {name:'Peter', age:95, gender:'boy'},
    {name:'Sebastian', age:50, gender:'boy'},
    {name:'Erika', age:27, gender:'girl'},
    {name:'Patrick', age:40, gender:'boy'},
    {name:'Samantha', age:60, gender:'girl'}
  ]">
    I have {{friends.length}} friends. They are:
    <input type="search" ng-model="q" placeholder="filter friends..." />
    <ul class="example-animate-container">
      <li class="animate-repeat" ng-repeat="friend in friends | filter:q" >
          <div on-finish-render="test($index)">
        [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
          </div>
      </li>
    </ul>
  </div>
</div>

CSS

</style> <!-- Ugly Hack to make remote files preload in jsFiddle --> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-animate.min.js"></script>
<script type="text/javascript" src="protractorTest.js"></script>
<style>.example-animate-container {
  background:white;
  border:1px solid black;
  list-style:none;
  margin:0;
  padding:0 10px;
}

.animate-repeat {
  line-height:40px;
  list-style:none;
  box-sizing:border-box;
}

.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
  -webkit-transition:all linear 0.5s;
  transition:all linear 0.5s;
}

.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
  opacity:0;
  max-height:0;
}

.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
  opacity:1;
  max-height:40px;
}

JavaScript

angular.module('App', [])
    .directive('onFinishRender', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                scope.$evalAsync(attr.onFinishRender);
            }
        }
    }
});

function myC($scope) {
    $scope.test = function(index) {
        alert('$last detected on '+ (index+1) );
    }
}