javascript - route - Angular js-mostrar/ocultar gif cargando cada nueva ruta
route in angular js (2)
(Un poco demasiado para poner en un comentario)
Configuré el código y vi que la variable de carga no se actualizaba cada vez y se debía al almacenamiento en caché de la plantilla, supongo que el ''RouteChange'' no se activa.
Desactivar el almacenamiento en caché de la plantilla permitirá que su código se ejecute cada vez.
app.run(function($rootScope, $location, $anchorScroll, $routeParams,$templateCache) {
$rootScope.$on(''$viewContentLoaded'', function() {
$templateCache.removeAll();
});
....
Estoy tratando de alternar (ocultar / mostrar) un gif de carga en cada nueva ruta, por lo que mi lógica sería:
- routeChangeStart = mostrar gif cargando
- routeChangeSuccess = ocultar gif de carga
Este es mi código:
//ANGULAR
app.run(function($rootScope) {
$rootScope.layout = {};
$rootScope.layout.loading = false;
$rootScope.$on(''$routeChangeStart'', function() {
//show loading gif
$rootScope.layout.loading = true;
});
$rootScope.$on(''$routeChangeSuccess'', function() {
//hide loading gif
$rootScope.layout.loading = false;
});
$rootScope.$on(''$routeChangeError'', function() {
//hide loading gif
alert(''wtff'');
$rootScope.layout.loading = false;
});
});
// HTML
<img src="img/loading.gif" ng-hide="!layout.loading"/>
es extraño porque esto funciona para 3/4 rutas cambiadas, entonces deja de funcionar mientras se cambian rutas: O
¿Qué podría ser?
AQUÍ HAY UN EJEMPLO EN VIVO gracias a @Rob Sedgwick: http://plnkr.co/edit/ZpkgRhEAoUGlnXjbLb8b
Respuesta corta : el $rootScope.layout.loading
cambió como se esperaba. Pero si las plantillas están cargadas, el navegador no tiene tiempo para hacer visibles los cambios.
Respuesta larga : si coloca salidas de console.log
en su $on
escuchas, verá que se dispara un evento $routeChangeStart
, la plantilla se carga y después de eso se dispara $routeChangeSuccess
. Bajo el capó sucede lo siguiente:
-
$routeChangeStart
incendios -
$rootScope.layout.loading
convierte entrue
- la plantilla se carga de forma asíncrona
- el DOM se actualiza
- el navegador muestra el gif de carga
un poco más tarde (devuelve la solicitud xhr)
- la plantilla fue cargada
-
$routeChangeSuccess
incendios -
$rootScope.layout.loading
vuelvefalse
- el DOM se actualiza
- El navegador ya no mostraba el gif.
¿Qué sucede si se almacenan en caché las placas de identificación: - $routeChangeStart
$rootScope.layout.loading
se $rootScope.layout.loading
- $rootScope.layout.loading
convierte en true
- $rootScope.layout.loading
se $rootScope.layout.loading
- $rootScope.layout.loading
vuelve false
- el DOM se actualiza (pero este es el mismo estado que antes)
Como puede ver, el navegador no puede mostrar el nuevo estado porque se está ejecutando una secuencia de comandos que no se interrumpe para que el navegador tenga tiempo de renderizar el DOM. Si la plantilla aún no está cargada, las solicitudes de ajax detienen la ejecución del script y le dan al navegador el tiempo para procesar el DOM.
¿Cómo arreglar esto?
Puede usar un timeout
que le dé tiempo al navegador para actualizar el DOM:
$rootScope.$on(''$routeChangeSuccess'', function () {
console.log(''$routeChangeSuccess'');
//hide loading gif
$timeout(function(){
$rootScope.layout.loading = false;
}, 200);
});
Aquí está su plunkr con esta solución: http://plnkr.co/edit/MkREo0Xpz5SUWg0lFCdu?p=preview