I am using AngularJS and ngProgress to display a YouTube-like loading bar at the top of my site.
The bar is started, then new data is loaded in via ajax, and once the request is finished, the bar is completed.
Example:
var TestCtrl = function( $scope, $location, Tests, ngProgress )
{
// start progressbar
ngProgress.start();
$scope.tests = Tests.query(
function()
{
// end progressbar
ngProgress.complete()
}
);
};
Now my question is: How can I integrate this principle higher up in the order of things, such that I don't have to repeat the code for every single controller?
You could use a service which controls ngProgress (acting like a wrapper over it) and listen for changes in the url.
$locationChangeSuccess is broadcasted (more info at $location) which we could listen to invoke ngProgress.start()ngProgress.complete() explicitly in our controllers OR we could assume that our async functions might take like 5 seconds to be completed and call ngProgress.complete() using a timer in our wrapper servicengProgress.reset()You can use the following approach to solve these problems:
angular.module('myApp').factory('Progress', function (ngProgress) {
var timer;
return {
start: function () {
var me = this;
// reset the status of the progress bar
me.reset();
// if the `complete` method is not called
// complete the progress of the bar after 5 seconds
timer = setTimeout(function () {
me.complete();
}, 5000);
},
complete: function () {
ngProgress.complete();
if (timer) {
// remove the 5 second timer
clearTimeout(timer);
timer = null;
}
},
reset: function () {
if (timer) {
// remove the 5 second timer
clearTimeout(timer);
// reset the progress bar
ngProgress.reset();
}
// start the progress bar
ngProgress.start();
}
};
});
To listen for changes in the url and show the progress bar we could use:
angular.module('myApp')
.run(function (Progress) {
$rootScope.$on('$locationChangeSuccess', function () {
Progress.start();
});
}
Now we can manually control the completeness of the status bar by injecting the Progress service and calling the method Progress.complete() when all of our async functions have finished (we could also control this from any service that makes async calls):
angular.module('myApp')
.controller('SomeCtrl', function (Progress) {
setTimeout(function () {
Progress.complete();
}, 2000);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With