Cargando Spinner en AngularJs
Presentaremos cómo agregar una rueda de carga mientras se carga la solicitud y detener el cargador cuando los datos se cargan en AngularJs.
Cargando Spinner en AngularJs
Los cargadores son parte de las aplicaciones web para que sean fáciles de usar y mejoren la interfaz de usuario. Los cargadores se muestran cuando la obtención de datos lleva más tiempo y, en lugar de mostrar una página en blanco, elegimos mostrar un cargador.
Las animaciones del cargador mantienen a los usuarios interesados mientras se cargan los datos. Veremos un ejemplo en el que mostraremos 6 imágenes y usaremos una animación de cargador para retrasar la visualización de imágenes.
Vamos a crear una nueva aplicación AngularJs para ver un ejemplo de directivas.
En primer lugar, agregaremos la biblioteca AngularJs usando etiquetas script
.
# AngularJs
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>
Ahora, definiremos la aplicación AngularJs usando ng-app
.
# AngularJs
<body ng-app="">
...
</body>
Crearemos un encabezado usando h2
. Después de eso, crearemos un div
con la clase loadImages
y la instrucción ng-if
que usará la variable images
; si se establece en verdadero, mostrará imágenes. Si se establece en false, las imágenes se ocultarán.
Dentro de nuestro div loadImages
, crearemos un div más con las clases img-box
que tendrá 2 div más dentro con las clases loader-box
e img
con declaraciones ng-if
. Solo se mostrará el div loader-box
si la variable loader
es true
.
Si el cargador es false
, oculta el cuadro del cargador y muestra imágenes. Dentro de nuestro loader-box
, crearemos una animación de cargador SVG, y dentro de nuestro div img
, mostraremos nuestra imagen.
Mostraremos 6 imágenes en nuestra plantilla copiando la estructura que acabamos de hacer. Así que nuestro código se verá como a continuación.
# AngularJs
<div class="container" ng-app="myApp" ng-controller="Controller">
<h2>Images Of Cat</h2>
<div ng-If="images == true" class="loadImages">
<div class="img-box">
<div ng-If="loader == true" class="loader-box">
<svg
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
width="200px"
height="200px"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid"
>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#e90c59"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="0s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="0s"
></animate>
</circle>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#46dff0"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
</circle>
</svg>
</div>
<div ng-If="loader == false" class="img">
<img
src="https://images.pexels.com/photos/3777622/pexels-photo-3777622.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
alt=""
/>
</div>
</div>
<div class="img-box">
<div ng-If="loader == true" class="loader-box">
<svg
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
width="200px"
height="200px"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid"
>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#e90c59"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="0s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="0s"
></animate>
</circle>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#46dff0"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
</circle>
</svg>
</div>
<div ng-If="loader == false" class="img">
<img
src="https://images.pexels.com/photos/156321/pexels-photo-156321.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
alt=""
/>
</div>
</div>
<div class="img-box">
<div ng-If="loader == true" class="loader-box">
<svg
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
width="200px"
height="200px"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid"
>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#e90c59"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="0s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="0s"
></animate>
</circle>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#46dff0"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
</circle>
</svg>
</div>
<div ng-If="loader == false" class="img">
<img
src="https://images.pexels.com/photos/3054570/pexels-photo-3054570.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
alt=""
/>
</div>
</div>
<div class="img-box">
<div ng-If="loader == true" class="loader-box">
<svg
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
width="200px"
height="200px"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid"
>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#e90c59"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="0s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="0s"
></animate>
</circle>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#46dff0"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
</circle>
</svg>
</div>
<div ng-If="loader == false" class="img">
<img
src="https://images.pexels.com/photos/6869634/pexels-photo-6869634.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
alt=""
/>
</div>
</div>
<div class="img-box">
<div ng-If="loader == true" class="loader-box">
<svg
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
width="200px"
height="200px"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid"
>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#e90c59"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="0s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="0s"
></animate>
</circle>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#46dff0"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
</circle>
</svg>
</div>
<div ng-If="loader == false" class="img">
<img
src="https://images.pexels.com/photos/7149465/pexels-photo-7149465.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
alt=""
/>
</div>
</div>
<div class="img-box">
<div ng-If="loader == true" class="loader-box">
<svg
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;"
width="200px"
height="200px"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid"
>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#e90c59"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="0s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="0s"
></animate>
</circle>
<circle
cx="50"
cy="50"
r="0"
fill="none"
stroke="#46dff0"
stroke-width="2"
>
<animate
attributeName="r"
repeatCount="indefinite"
dur="1s"
values="0;40"
keyTimes="0;1"
keySplines="0 0.2 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
<animate
attributeName="opacity"
repeatCount="indefinite"
dur="1s"
values="1;0"
keyTimes="0;1"
keySplines="0.2 0 0.8 1"
calcMode="spline"
begin="-0.5s"
></animate>
</circle>
</svg>
</div>
<div ng-If="loader == false" class="img">
<img
src="https://images.pexels.com/photos/320014/pexels-photo-320014.jpeg?auto=compress&cs=tinysrgb&w=175&fit=crop&h=275&dpr=1"
alt=""
/>
</div>
</div>
</div>
Una vez que hayamos agregado imágenes, agregaremos 2 botones, uno ocultará las imágenes y otro cargará las imágenes. Usaremos la instrucción ng-if
para ocultar los botones cuando no se necesiten.
Por ejemplo, el botón load images
no aparecerá cuando se muestren las imágenes. El botón hide images
no se mostrará cuando las imágenes estén ocultas.
Estos botones también tendrán eventos ng-Click
para las funciones loadImages()
y hideImages()
, respectivamente.
<button ng-If="images == false" ng-click="loadImages()">
Click to view Images
</button>
<button ng-If="images == true" ng-click="hideImages()">
Click to hide Images
</button>
</div>
Escribamos algo de CSS para organizar nuestras imágenes y el cargador. Entonces nuestro código en CSS será el siguiente.
p {
font-family: Lato;
}
h2 {
text-align: center;
}
.img-box {
width: 31%;
float: left;
border: 1px solid black;
margin-right: 5px;
margin-bottom: 5px;
}
.img-box svg {
width: 100%;
}
.img-box .img {
width: 100%;
height: 200px;
overflow: hidden;
}
Definiremos 2 variables dentro de nuestro archivo Js
llamados loader
y images
. Los usaremos en declaraciones ng-if
y los configuraremos como falsos para ocultarlos al cargar imágenes.
Crearemos las funciones que usamos en el evento ng-click
en los botones. En loadImages
, primero estableceremos loader
en true
y crearemos una función setTimeout
para retrasar la animación del cargador durante 2000 ms.
Después de 2000ms, cambiaremos el valor de loader
a false
y pondremos el valor de images
a true
para mostrar las imágenes con una animación de carga.
Ahora, en la función hideImages()
solo estableceremos el valor de images
en false
. Entonces, el código en nuestro archivo index.js
se verá como a continuación.
var myApp = angular.module('myApp', [])
.controller('Controller', function($scope){
$scope.loader = false;
$scope.images = false;
$scope.loadImages = function(){
$scope.loader = true;
setTimeout(function () {
$scope.$apply(function(){
$scope.loader = false;
});
}, 2000);
$scope.images = true;
};
$scope.hideImages = function(){
$scope.images = false;
};
});
Puedes consultar el código aquí.
Veamos cómo funciona nuestra aplicación.
Producción:
De esta forma, podemos configurar una animación de carga para cualquier elemento de nuestra aplicación AngularJs.
Pero las animaciones del cargador se usan principalmente en solicitudes HTTP
porque a veces toman tiempo, y es mejor usar animaciones de carga para mantener al usuario interesado en lugar de mostrar una página en blanco hasta que se carguen los datos.
Rana is a computer science graduate passionate about helping people to build and diagnose scalable web application problems and problems developers face across the full-stack.
LinkedIn