Reputation: 574
I want to create an effect where user wait 2-3 seconds between each page; currently I have in my html page a div with .page-loading class; and in my run script I have the code below;
I also get no errors whatsoever and the loading is constantly showing!
app.run.js
(function() {
'use strict';
angular.module('app')
.run(run);
run.$inject = ['$window', '$rootScope', '$timeout'];
function run($window, $rootScope, $timeout) {
//Loading
var delay = 1000;
$rootScope
.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
$timeout(function() {
$(".page-loading").removeClass("ng-hidden");
$(".page").addClass("ng-hidden");
}, delay);
});
$rootScope
.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams) {
$timeout(function() {
$(".page-loading").addClass("ng-hidden");
$(".page").removeClass("ng-hidden");
}, delay);
});
};
})();
My View code
<div class="page-loading ng-hidden">Loading...</div>
<div ui-view class="page"></div>
Upvotes: 0
Views: 3547
Reputation: 38490
Not sure if you have your own ng-hidden
class, otherwise you should use ng-hide
.
Other than that, there are a few timing issues in your code.
Unless you have states that take really long to load (for example if you use resolve
) there won't be much delay at all between the events $stateChangeStart
and $stateChangeSuccess
. This means that the two functions passed to $timeout
will fire right after each other and for example the loader element will have a class removed then instantly added again.
Below is an example with comments of what I believe you are trying to achieve.
var hideClass = 'ng-hide',
delay = 1000,
firstChangeStartt = false,
firstContentLoaded = false,
timer;
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
// Remove this if you want the loader + delayed view behavior when first entering the page
if (!firstChangeStartt) {
firstChangeStartt = true;
return;
}
// Cancel the ongoing timer (if any)
// This is used not to get weird behaviors if you change state before the previous has finished loading
$timeout.cancel(timer);
// Show the loader and hide the old view as soon as a state change has started
$(".page-loading").removeClass(hideClass);
$('.page').addClass(hideClass);
});
// Use '$viewContentLoaded' instead of '$stateChangeSuccess'.
// When '$stateChangeSuccess' fires the DOM has not been rendered and you cannot directly query the elements from the new HTML
// When '$viewContentLoaded' fires the new DOM has been rendered
$rootScope.$on('$viewContentLoaded',
function(event, toState, toParams, fromState, fromParams) {
// Remove this if you want the loader + delayed view behavior when first entering the page
if (!firstContentLoaded) {
firstContentLoaded = true;
return;
}
$timeout.cancel(timer);
// Hide the new view as soon as it has rendered
var page = $('.page');
page.addClass(hideClass);
// Hide the loader and show the new view after a delay
// Pass false as the third argument to prevent the digest loop from starting (since you are just modifying CSS there is no reason for Angular to perform dirty checking in this example)
timer = $timeout(function() {
page.removeClass(hideClass);
$(".page-loading").addClass(hideClass);
}, delay, false);
});
If you have any questions just let me know.
Demo: http://plnkr.co/edit/bpMvgFEArfiJQ5EgIrfG?p=preview
Upvotes: 2