Reputation: 1445
Here a sample codepen to explain my needs.
Basically I'm running a 2-pages Ionic application.
Page 1 is nothing but an hyperlink to page 2.
Page 2 reads data from an external source and requires some time (2 seconds).
I'd like to show a loading indicator while page 2 is "loading" that inhibits every user action on that page. Is there any good patterns to achieve this goal? I can probably use scope variables such as showPage
and angularJs ng-show
or something like that, but I would avoid to copy this pattern in every page.
Any idea?
Upvotes: 2
Views: 1902
Reputation: 35587
You can use angular-block-ui.
It is very simple to implement in your project. Once you've referenced the css:
<link rel="stylesheet" href="path-to-block-ui/angular-block-ui.min.css"/>
and the javascript:
<script src="path-to-block-ui/angular-block-ui.min.js"></script>
you can add the dependency to your module:
angular.module('myApp', ['blockUI'])
It uses interceptors for long http calls. You can see how it works in the Block on HTTP requests in the examples page.
In your situation things are slightly different cause there's no http request there (I know, it's a demo) so you have to force the ui block manually. You can change the service injecting the dependecy to blockUI:
.factory('MyService', function($q, blockUI) { ... })
and call blockUI.start();
right before the long running process and blockUI.stop();
when the promise is resolved.
.factory('MyService', function($q, blockUI) {
var items = ['1', '2', '3', '4', '5'];
return {
all: function() {
var deferred = $q.defer();
blockUI.start();
setTimeout(function() {
deferred.resolve(items);
blockUI.stop();
}, 2000);
return deferred.promise;
}
}
})
See your modified sample here.
In one of my apps I've used another angular module called angular-loading-bar. I guess it is the most popular these days. This one works with interceptors as well but it doesn't block the UI.
The third option is to use the ionic $ionicLoading
service.
You have to do a little bit of extra work here as this service only show a loading indicator and blocks the interface.
You can create an interceptor:
var app = angular.module('ionicApp', ['ionic'])
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function($rootScope) {
return {
request: function(config) {
$rootScope.$broadcast('loading:show')
return config
},
response: function(response) {
$rootScope.$broadcast('loading:hide')
return response
}
}
})
})
which listens to http requests and broadcasts an event loading:show
.
When the server has responded with some data the interceptor broadcasts loading:hide
.
Your app would intercept those events when the app runs:
app.run(function($rootScope, $ionicLoading) {
$rootScope.$on('loading:show', function() {
$ionicLoading.show({template: 'foo'})
})
$rootScope.$on('loading:hide', function() {
$ionicLoading.hide()
})
})
Upvotes: 2
Reputation: 1445
Answering my own question: $ionicLoading is what I was looking for.
Upvotes: 0