J'ai un service dans Angular qui utilise mon API pour obtenir des informations utilisateur et les fournit à mes contrôleurs. C'est mis en place comme ça:
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
.service('userInfo', function($http, $cookies){
$http.get('/api/users/' + $cookies.id).
success(function(data) {
var userInfo = data.user[0];
return userInfo;
});
}). // other stuff comes after this
Dans mes contrôleurs, je l’inclus comme:
function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
$scope.user = userInfo;
console.log('user info is')
console.log(userInfo);
Cela ne renvoie aucune donnée, alors que si je mets la même fonction de service dans le contrôleur, elle retourne très bien. Qu'est-ce que j'oublie ici? Jamais utilisé DI/Services dans Angular auparavant, cela pourrait donc être une simple erreur quelque part.
Je dois m'assurer que le service renvoie les donnéesavantle contrôleur se charge. Comment cela peut-il être accompli
Vous pouvez faire l'usine pour retourner une promesse comme ceci:
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
.service('userInfo', function ($http, $cookies) {
var promise = $http.get('/api/users/' + $cookies.id).
success(function (data) {
var userInfo = data.user[0];
return userInfo;
});
return promise;
}) // other stuff comes after this
Et dans votre contrôleur, faites
function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
userInfo.then(function(data){
$scope.user = data;
});
}
Cela peut garantir que chaque fois que vous utilisez le service, il vous donne toujours les données de manière synchrone , vous ne devez pas nécessairement charger de données avant de charger le contrôleur.
Votre service userInfo
doit renvoyer la promesse retournée par $http
. Cette promesse sera ensuite injectée dans votre contrôleur et la vue sera mise à jour dès que la promesse sera résolue.
Si vous ne souhaitez pas que la vue soit rendue avant la résolution de userInfo
, vous devez définir une propriété resolve
sur votre route et y injecter votre service:
$routeProvider.when('/profile', {
templateUrl: 'profile',
controller: userProfile,
resolve: {
userInfoData: function ($q, userInfo) {
return userInfo;
}
}
});
Ensuite, injectez simplement userInfoData
dans votre contrôleur à la place du service userInfo
.
J'ai rencontré le même problème dans lequel je devais charger des données dans un service en utilisant $ resource et obtenir ces données dans les contrôleurs $ scope . Je ne voulais pas retourner directement la promesse et ensuite utiliser un résolveur dans le contrôleur (@zsong a écrit) mais pour faire toute la magie dans le service une fois et utiliser la possibilité d'attribuer une promesse directement à un $ scope comme le souligne @Joseph Silber, voici ce que j'ai fait:
return function($scope){promise.then(function(data){$scope.user = data})};
Et utilisé dans le contrôleur comme ceci:
userInfo($scope);
Pas beaucoup d'amélioration mais cela m'a permis une syntaxe plus claire dans mes contrôleurs, j'espère que ça va aider même trois ans plus tard!
Vous pouvez affecter l'objet de ressource à votre variable de la manière suivante: