Mon problème est que j'ai besoin d'un service chargé avant que le contrôleur soit appelé et que le modèle soit rendu. http://jsfiddle.net/g75XQ/2/
Html:
<div ng-app="app" ng-controller="root">
<h3>Do not render this before user has loaded</h3>
{{user}}
</div>
JavaScript:
angular.module('app', []).
factory('user',function($timeout,$q){
var user = {};
$timeout(function(){//Simulate a request
user.name = "Jossi";
},1000);
return user;
}).
controller('root',function($scope,user){
alert("Do not alert before user has loaded");
$scope.user = user;
});
La
Vous pouvez différer l'initialisation de angular en utilisant initialisation manuelle , au lieu de l'initialisation automatique avec ng-app
attribut.
// define some service that has `$window` injected and read your data from it
angular.service('myService', ['$window', ($window) =>({
getData() {
return $window.myData;
}
}))
const callService = (cb) => {
$.ajax(...).success((data)=>{
window.myData = data;
cb(data)
})
}
// init angular app
angular.element(document).ready(function() {
callService(function (data) {
doSomething(data);
angular.bootstrap(document);
});
});
où callService
est votre fonction exécutant AJAX appel et acceptant le rappel de succès, qui initiera angular app.
Vérifiez également la directive ngCloak
, car elle contient peut-être tout ce dont vous avez besoin.
Alternativement, lorsque vous utilisez ngRoute vous pouvez utiliser la propriété resolve
, pour cela vous pouvez voir la réponse @honkskillet
encore mieux que l'amorçage manuel (ce qui n'est pas toujours une mauvaise idée non plus).
angular.module('myApp', ['app.services'])
.run(function(myservice) {
//stuff here.
});
Comme je l'ai dit dans les commentaires, il serait beaucoup plus facile de gérer un état non chargé dans votre contrôleur, vous pouvez bénéficier de $ q pour le rendre très simple: http://jsfiddle.net/g/g75XQ/ 4 /
si vous voulez faire quelque chose dans le contrôleur lorsque l'utilisateur est chargé: http://jsfiddle.net/g/g75XQ/6/
EDIT: Pour retarder le changement d'itinéraire jusqu'à ce que certaines données soient chargées, regardez cette réponse: Retarder le changement d'itinéraire AngularJS jusqu'au chargement du modèle pour éviter le scintillement
La bonne façon d'y parvenir est d'utiliser la propriété de résolution sur la définition des routes: voir http://docs.angularjs.org/api/ngRoute.$routeProvider
puis créez et retournez une promesse en utilisant le service $ q; utilisez également $ http pour faire la demande et sur réponse, résolvez la promesse.
De cette façon, lorsque l'itinéraire est résolu et que le contrôleur est chargé, le résultat de la promesse sera déjà disponible et aucun scintillement ne se produira.
Vous pouvez utiliser la résolution dans le .config $ routeProvider. Si une promesse est retournée (comme c'est le cas ici), l'itinéraire ne se chargera pas tant qu'il ne sera pas résolu ou rejeté. De plus, la valeur de retour sera disponible pour être injectée dans le contrôleur (dans ce cas Somert).
angular.module('somertApp')
.config(function($routeProvider) {
$routeProvider
.when('/home/:userName', {
/**/
resolve: {
Somert: function($q, $location, Somert) {
var deferred = $q.defer();
Somert.get(function(somertVal) {
if (somertVal) {
deferred.resolve(somertVal);
} else {
deferred.resolve();
$location.path('/error/'); //or somehow handle not getting
}
});
return deferred.promise;
},
},
});
});
Il existe plusieurs méthodes, certaines plus avancées que d'autres, mais dans votre cas, ng-hide fait l'affaire. Voir http://jsfiddle.net/roytruelove/g75XQ/3/