AngularJS $ http dans un service, renvoyer des données résolues, pas des promesses
Je veux savoir si il est possible de faire un appel de service qui utilise $http
afin qu'il renvoie directement les données sans avoir à retourner une promesse? J'ai essayé d'utiliser le $q
et de reporter sans un peu de chance.
Voici ce que je veux dire:
J'ai un service:
angular.module('myModule').factor('myService', ['$http', '$q',
function($http, $q) {
//Public API
return {
myServiceCall: function() {
return $http.get('/server/call');
}
};
}
]);
Et ce est la façon dont je l'appellerais:
//My controller:
myService.myServiceCall().then(function(data) {
$scope.data = data;
});
Je veux éviter que la et plutôt souhaitez avoir:
$scope.data = myService.myServiceCall();
Je veux qu'il soit entièrement réglé à cette ligne, c'est possible?
J'ai essayé quelques combinaisons de $q, reporter et 'puis' méthodes, mais ne réussissent pas à obtenir de droit, puisque la méthode retourne immédiatement.
Edit:
Si vous vous demandez pourquoi, la raison principale est que j'ai voulu simplifier le code du contrôleur, cela se fait facilement avec ngResource que ces appels sont automatiquement résolus dans les modèles, donc j'ai voulu éviter le besoin de faire du tout".ensuite,' a chaque fois.
Ce n'est pas que je n'aime pas la nature Asynchrone, la plupart de nos code exploite, c'est juste dans la certains cas, d'avoir une façon synchrone est utile.
Je pense que pour l'instant, comme certains d'entre vous l'ont souligné, je vais utiliser le $ressource, pour un assez proche de la solution.
source d'informationauteur iQ.
Vous devez vous connecter pour publier un commentaire.
Il y a deux façons que je peux penser à le faire. La première est certainement mieux que le deuxième.
La première façon de le faire: à l'aide de la
resolve
propriété de routesVous pouvez utiliser le
resolve
propriété de l'itinéraire de l'objet de configuration pour spécifier qu'une promesse doit être résolu et la valeur résolue être utilisé pour la valeur de l'un de vos contrôleur de dépendances, de sorte que dès que votre contrôleur exécute, la valeur est immédiatement disponible.Par exemple, disons que vous avez le service suivant:
Ensuite, vous pouvez définir votre itinéraire à quelque chose comme ceci:
La clé dans le
resolve
objet correspond au nom de la deuxième dépendance pour le contrôleur, donc, même si elle renvoie une promesse, cette promesse sera résolu avant que le contrôleur est exécuté.La deuxième façon: en Faire la demande bien avant que vous avez besoin de données
La seconde manière, qui n'est pas du tout idéal, et sera susceptible de vous mordre sur les fesses à un certain point, c'est de faire la demande pour les données dès le début, comme quand votre application est initialisé, et puis d'obtenir les données plus tard, par exemple sur une page qui nécessite 3 clics pour obtenir à partir de la page d'accueil. Croisons les doigts, si les astres sont alignés, votre demande http aura retourné et vous aurez les données à utiliser.
Puis, dans votre module de la fonction d'exécution, en faire la demande:
Puis, dans un contrôleur pour une page qui est garanti pour fonctionner au moins 3 secondes après l'application démarre, vous pouvez faire comme vous l'avez suggéré:
Bonus, aussi mauvais l'un troisième moyen: Synchrone requête AJAX
Faire comme ricick suggère, et d'utiliser la machine synchrone à une requête AJAX possible avec jQuery
.ajax()
méthode.Ce n'est pas possible, que http appels sont intrinsèquement asynchrone. Qui est, vous devez attendre que le serveur réponde.
Le $service des ressources est autour de cette en retournant un objet proxy qui est rempli avec les données renvoyées sur la réponse du serveur, mais il n'est pas encore entièrement résolu en une seule ligne.
Edit:
Il est effectivement possible de faire synchrone requêtes http avec l'ajax de jquery méthode, en définissant l'option "async" pour de faux.
Vous pouvez créer un service qui encapsule tout cela, cependant, votre demande de "lock-up" alors que la demande attend une réponse du serveur, donc dans la plupart des cas, ce serait une mauvaise pratique. Il existe également d'autres restrictions sur ce type de demande.
Voir la documentation pour plus de détails:
http://api.jquery.com/jQuery.ajax/
Il y a longtemps (dans angulaire de la terre, en fait courant de l'année dernière) c'était en fait la façon dont il fonctionne.
Mais maintenant ce n'est plus le cas, je pense que c'est dû à des différences de comportement de la promesse de vue et contrôleur, voici plus sur la désapprobation :
Angularjs promets pas de liaison à un modèle en 1.2