Short version
When ui-router moves to a new view (using ngAnimate in some way, which I don't fully understand), it adds the ng-leave and ng-leave-active classes to the current view. It also adds the ng-enter and ng-enter-active classes to the next view. The problem is that the transition begins before all DOM changes in the next view are complete, which will cause the transition to be aborted. So my question is: is it possible to prevent the addition of the ng-enter and ng-enter-active classes until I decide that they should be added (by sending an event from the controller or such)?
Long version
I am developing an AngularJS application that uses ui-router and ng-animate for transitions. I ran into a small performance issue that I really would like to solve in order to make the application smoother.
Transitions between states seem stuttering, and I discovered that this is probably because Angular performs DOM changes during the transition during the transition.
How can I make sure that the DOM changes in the next view are complete before the transition? I use the ui-router permission function along with promises, which prevents the transition to loading data.
I created a JSFiddle that illustrates my problem. When you click a link to enter state2, it is required that the permission lines are processed with data (as expected). However, it looks like the DOM is ready when the transition occurs, since the transition can be quite slow. This makes me think that the DOM is not ready when the transition occurs.
app.js
angular.module('myApp', ['ui.router', 'ngAnimate']) .config(['$stateProvider', function ($stateProvider) { $stateProvider .state('state1', { url: '', views: { 'main': { templateUrl: "state1.html", controller: function(){ } } } }) .state('state2', { url: '/state2', views: { 'main': { templateUrl: "state2.html", controller: function($scope, rows){ $scope.rows = rows; }, resolve: { rows: function($q){ var rows = []; var deferred = $q.defer(); for (var i = 0; i < 10000; i++){ rows.push({a: i, b: i/2, c: 3*i/2}); } deferred.resolve(rows); return deferred.promise; } } } } }); }])
Patterns
<div ui-view="main" class="main"></div> <script type="text/ng-template" id="state1.html"> <a ui-sref="state2">Go to state 2</a> </script> <script type="text/ng-template" id="state2.html"> <a ui-sref="state1">Back to state 1</a> <table> <tr> <th>a</th> <th>b</th> <th>c</th> </tr> <tr ng-repeat="row in rows"> <td>{{row.a}}</td> <td>{{row.b}}</td> <td>{{row.c}}</td> </tr> </table> </script>
CSS
.main{ transition: all 1s ease; position: absolute; width: 100%; } .main.ng-enter{ transform: translateX(30%); opacity: 0; } .main.ng-enter.ng-enter-active{ transform: translateX(0); opacity: 1; } .main.ng-leave{ transform: translateX(0); opacity: 1; } .main.ng-leave.ng-leave-active{ transform: translateX(-30%); opacity: 0; }