Reputation: 3573
I want to use a spinner which I can show during some of the rest api calls for a better UX. I have come across many existing github projects which does exactly similar things.
https://github.com/cgross/angular-busy
https://github.com/urish/angular-spinner
But I'm not able to use any of the existing projects. I think before I start writing something of my own, I want to know if things which I'm looking for can be done using these projects or any other existing project.
Requirement:
I think angular-busy demo does solves most of the above requirements except that it needs a promise param in html. Is there anyway by which I can control the start/stop dynamically from my controller rather than giving a promise.
Angular-spinner demo is good but it doesn't fade out background. Is there any way to fade out background ?
Can anyone give me some pointers how exactly can I solve my problem ?
Upvotes: 2
Views: 4699
Reputation: 2970
It seems like http://bsalex.github.io/angular-loading-overlay/_site/ fits the requirements.
For example:
var app = angular.module('app-http-integration-with-reference-id-and-matchers', [
'bsLoadingOverlay',
'bsLoadingOverlayHttpInterceptor'
])
.factory('randomTextInterceptor', function(bsLoadingOverlayHttpInterceptorFactoryFactory) {
return bsLoadingOverlayHttpInterceptorFactoryFactory({
referenceId: 'random-text-spinner',
requestsMatcher: function(requestConfig) {
return requestConfig.url.indexOf('hipsterjesus') !== -1;
}
});
})
.factory('randomUserInterceptor', function(bsLoadingOverlayHttpInterceptorFactoryFactory) {
return bsLoadingOverlayHttpInterceptorFactoryFactory({
referenceId: 'random-user-spinner',
requestsMatcher: function(requestConfig) {
return requestConfig.url.indexOf('randomuser') !== -1;
}
});
})
.config(function($httpProvider) {
$httpProvider.interceptors.push('randomTextInterceptor');
$httpProvider.interceptors.push('randomUserInterceptor');
}).run(function($sce, bsLoadingOverlayService) {
bsLoadingOverlayService.setGlobalConfig({
/*
It is only an example, don't use this url in production.
Copy this template to your code base or use integration with Spin.js (see Docs & Examples)
*/
templateUrl: $sce.trustAsResourceUrl('https://raw.githubusercontent.com/bsalex/angular-loading-overlay/gh-pages/_site/loading-overlay-template.html')
});
});
app.controller('HttpIntegrationWithReferenceIdAndMatchersController', function($scope, $http, $sce, bsLoadingOverlayService) {
$scope.randomText = $sce.trustAsHtml('Fetch result here');
$scope.randomUser = undefined;
$scope.fetchRandomText = function() {
$http.get('http://hipsterjesus.com/api/')
.success(function(data) {
$scope.randomText = $sce.trustAsHtml(data.text);
})
.error(function() {
$scope.randomText = $sce.trustAsHtml('Can not get the article');
});
};
$scope.fetchRandomUser = function() {
$http.get('https://randomuser.me/api/')
.success(function(data) {
$scope.randomUser = data.results[0];
});
};
});
.random-result {
display: flex;
height: 170px;
margin-top: 1em;
}
.random-result__text,
.random-result__user {
position: relative;
overflow: auto;
border: 2px dashed #C00;
flex: 1;
margin: 0.5em;
padding: 0.5em;
text-align: center;
}
.user__photo {
width: 100px;
height: 100px;
border-radius: 50%;
margin: 0;
}
.user__name {
font-size: 1.5em;
margin: 0.5em;
padding: 0;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="https://rawgit.com/bsalex/angular-loading-overlay/master/dist/angular-loading-overlay.js"></script>
<script src="https://rawgit.com/bsalex/angular-loading-overlay-http-interceptor/master/dist/angular-loading-overlay-http-interceptor.js"></script>
<div ng-app="app-http-integration-with-reference-id-and-matchers">
<div ng-controller="HttpIntegrationWithReferenceIdAndMatchersController">
<div class="well well-lg bs-loading-container">
<button ng-click="fetchRandomText()">Fetch random text</button>
<button ng-click="fetchRandomUser()">Fetch random user</button>
<div class="random-result">
<div class="random-result__text" bs-loading-overlay bs-loading-overlay-reference-id="random-text-spinner" bs-loading-overlay-delay="3000">
<p ng-bind-html="randomText"></p>
</div>
<div class="random-result__user user" bs-loading-overlay bs-loading-overlay-reference-id="random-user-spinner" bs-loading-overlay-delay="3000">
<div ng-if="randomUser">
<img ng-src="{{randomUser.picture.large}}" alt="" class="user__photo" />
<p class="user__name">
{{randomUser.name.first}} {{randomUser.name.last}}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
In the snippet above I've used integration with $http service. It matches requests and shows spinner with specified referenceId
.
Also, the following features are available:
bsLoadingOverlayService.start();
and bsLoadingOverlayService.stop();
;bsLoadingOverlayService.wrap()
;bsLoadingOverlayService.createHandler({referenceId: 'handler-overlay'});
), to keep options in one place and then just call preconfiguredHandler.start();
and preconfiguredHandler.stop();
Upvotes: 1
Reputation: 351
I always create my own spinner with this logic:
js:
app.directive('ngSpinnerBar', ['$rootScope',
function ($rootScope) {
return {
link: function (scope, element, attrs) {
// by defult hide the spinner bar
element.addClass('hide');
// count how many time requests were sent to the server
// so when they all done the spinner will be removed
scope.counter = 0;
$rootScope.$on('$stateNetworkRequestStarted', function () {
scope.counter++;
element.removeClass('hide'); // show spinner bar
// $('body').addClass('page-on-load');
});
$rootScope.$on('$stateNetworkRequestEnded', function () {
scope.counter--;
if (scope.counter <= 0) {
scope.counter = 0;
element.addClass('hide'); // show spinner bar
// $('body').removeClass('page-on-load'); // remove page loading indicator
}
});
}
};
}
])
html:
<div ng-spinner-bar></div>
As you can see every time i send a request to the api i show the spinner (css create the spinning - link) and when result come back i send event to hide the spinner.
if you want to make things easier for you, you should create a service which send all the api requests (wrap $http). that way you can ensure every request will show the spinner.
EDIT
the first result in google gave me this - fade background in angular
Upvotes: 2