Comment faire un indicateur de chargement pour chaque action asynchrone (à l'aide de $q) dans un angularjs-app
Je sais qu'il existe plusieurs approches pour le chargement-indicateurs en angular js (celui-ci, par exemple: https://gist.github.com/maikeldaloo/5140733).
Mais ils doivent être configurés pour chaque appel, ou - s'ils agissent à l'échelle mondiale, comme je veux, il suffit d'appliquer à http demandes, mais pas de $q-promet d'être utilisée dans les services.
Le mondial indicateurs de chargement, j'ai vu jusqu'à présent, le travail avec
$httpProvider.responseInterceptors.push(interceptor);
Est-il quelque chose de similaire pour $q
, comme un $qProvider.reponseInterceptors
? Et si non, quel serait le moyen le plus pratique de mettre en œuvre une telle fonctionnalité? Est-il possible d'utiliser un décorateur-motif d'un certain type, par exemple?
- J'espère que vous obtiendrez une réponse sur ce point, mais sinon je serais probablement commencer à enquêter sur l' $q code angulaire pour voir si vous pouvez faire un patch sur votre copie ou même potentiel de soumettre une demande d'extraction si rien de tel n'existe. Il y a également une longue mais très belle écriture sur la mise en œuvre de Q qui angulaire emprunté et allégée: github.com/kriskowal/q
- Vous pensez vraiment que c'est une bonne idée de marteau cette fonctionnalité directement à
$q
? Que faire si je ne veux PAS l'indicateur à afficher (par exemple, pour une promesse créé par une boîte de dialogue modale, pas une requête AJAX)? En outre, il est assez simple à faire avec un service. Dans mon projet actuel, c'est fait avec une seule ligne à chaque fois que j'ai besoin de bloquer l'INTERFACE utilisateur sur une promesse, ou$resource
:uiBlocker.block(promise)
. - pas dans toutes les circonstances. Mais pour les petits projets, ce serait très gentil. D'autre part, je pense qu'il serait intelligent de façons de gérer une telle fonctionnalité, quand il y a une sorte de mondial de chargement de l'état disponible. Je serais intéressé par l'explication plus détaillée de votre approche si!
Vous devez vous connecter pour publier un commentaire.
Bien que je trouve qu'il est très compliqué, inutile, et sans doute cassé, vous pourrait décorer
$q
et de remplacer sondefer
fonction.Chaque fois quelqu'un demande pour un nouveau
defer()
il exécute votre propre version qui a également incrémente un compteur. Avant de distribuer ledefer
objet, vous vous inscrivez à unfinally
de rappel (Angulaire 1.2.0 seulement, maisalways
peut convenir aussi) pour décrémenter le compteur.Enfin, vous ajoutez une montre à
$rootScope
à surveiller lorsque ce compteur est supérieur à 0 (plus rapide que d'avoirpendingPromisses
dans$rootScope
et lier commeng-show="pendingPromisses > 0"
).Puis, vue lié à un champ d'application qui hérite de
$rootScope
peut avoir:(cela ne fonctionnera pas dans les directives isoler les étendues)
Voir en direct ici.
$q
est d'un usage général, async utilitaire de programmation qui ne peuvent indiquent généralement que quelque chose est en cours de chargement. Il peut être utilisé en interne par d'autres (par un tiers) des modules qui ne savent pas à propos de votre convention. Et puis, votre retour à la case départ. Chargement de toupies, signifie généralement "l'attente du serveur" (un.k.un$httpProvider.interceptors
). Tout le reste doit être très rapide.$q
en interne, aussi. Et, peut-être, contre incr/decr se passe si vite que vous ne pouvez pas voir le spinner de rendu.$q.defer()
sémantique ne vous forcent pas à les résoudre ou de les rejeter. Vous pouvez faire autant de nouvellesdefer
objets que vous le souhaitez et de les jeter (vous ou une autre bibliothèque). À partir de maintenant, vous à assurez-vous que ils être résolus ou rejetée avant que vous manquez de référence, à défaut de quoi votre spinner ne sera jamais se cacher à nouveau. J'espère que vous n'aurez pas à ajouter$scope.$on('$destroy', function() { /* reject here */ });
provoquer ce serait battre le but de celui-ci.Il y a un bon exemple dans la documentation officielle de travail pour la version stable actuelle 1.2.0.
http://docs.angularjs.org/api/ng.$http (quart supérieur de la page de recherche pour les Intercepteurs)
Mon extraction de ces documents m'ont mené à cette solution:
Vous pouvez ensuite utiliser pendingRequests>0 dans un ng-show expression.
Depuis demandé par l'OP, c'est basé sur la méthode que nous utilisons pour l'application que nous sommes en train de travailler. Cette méthode ne PAS changer le comportement de
$q
, plutôt ajoute un très simple API pour gérer les promesses qui ont besoin d'une indication visuelle. Bien que ce besoin d'être modifié à chaque endroit où il est utilisé, il n'est qu'un one-liner.D'utilisation
Il y a un service, dire
ajaxIndicator
, qui sait comment mettre à jour une partie de l'INTERFACE utilisateur. Chaque fois qu'une promesse, comme objet doit donner une indication jusqu'à ce que la promesse est résolu que nous utilisons:Si vous ne souhaitez pas conserver une référence à la promesse:
Ou avec une ressource:
(NOTE: Pour Angulaires 1.2 ce besoin tweeking, comme il n'y a pas de
$then()
sur l'objet de la ressource.)Maintenant à la racine du modèle, vous devez lier l'indicateur de
$rootScope.ajaxActive
, par exemple:Mise en œuvre
(Modifié à partir de notre source.) AVERTISSEMENT: Cette application ne prend pas en compte les appels imbriqués! (Nos exigences demandées pour l'INTERFACE utilisateur de blocage, de sorte que nous ne nous attendons pas les appels imbriqués; si intéressé je pourrais essayer d'améliorer ce code.)
J'ai eu la même grande question il ya quelques semaines et il m'arrive de faire quelques directives pour représenter le chargement de l'état sur les boutons d'action et ng-repeat chargement du contenu.
J'ai juste passé un peu de temps et poussé sur github:
https://github.com/ocolot/angularjs_loading_buttons
J'espère que cela aide.