AngularJS: appelle une fonction particulière avant tout contrôleur de page partiel
Je veux appeler une fonction particulière: GetSession()
au début de mon chargement de l'application. Cette fonction rend un $http
appeler et obtenir un jeton de session: GlobalSessionToken
à partir du serveur. Ce jeton de session est ensuite utilisé dans d'autres contrôleurs de logique et d'extraire des données à partir du serveur. J'ai appeler ce GetSession()
dans le contrôleur principal: MasterController
dans $routeChangeStart
événement, mais comme un appel asynchrone, mon code va de l'avant à CustomerController
avant la $http
réponse.
Voici mon code:
var GlobalSessionToken = ''; //will get from server later
//Define an angular module for our app
var myApp = angular.module('myApp', ['ngRoute']);
//Define Routing for app
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/customer', {
templateUrl: 'partials/customer.html',
controller: 'CustomerController',
resolve: {
loadData: function($q){
return LoadData2($q,'home');
}
}
}).
otherwise({
redirectTo: '/home'
});
}]);
//controllers start here and are defined in their each JS file
var controllers = {};
//only master controller is defined in app.js, rest are in separate js files
controllers.MasterController = function($rootScope, $http){
$rootScope.$on('$routeChangeStart', function(){
if(GlobalSessionToken == ''){
GetSession();
}
console.log('START');
$rootScope.loadingView = true;
});
$rootScope.$on('$routeChangeError', function(){
console.log('ERROR');
$rootScope.loadingView = false;
});
};
controllers.CustomerController = function ($scope) {
if(GlobalSessionToken != ''){
//do something
}
}
//adding the controllers to myApp angularjs app
myApp.controller(controllers);
//controllers end here
function GetSession(){
$http({
url: GetSessionTokenWebMethod,
method: "POST",
data: "{}",
headers: { 'Content-Type': 'application/json' }
}).success(function (data, status, headers, config) {
GlobalSessionToken = data;
}).error(function (data, status, headers, config) {
console.log(data);
});
}
Et mon HTML a sections suivantes:
<body ng-app="myApp" ng-controller="MasterController">
<!--Placeholder for views-->
<div ng-view="">
</div>
</body>
Comment puis-je m'assurer que ce GetSession()
est toujours appelé au tout début de mon démarrage de l'application et avant tout autre contrôleur appels et a également appelé qu'une seule fois.
EDIT: C'est comment j'ai ajouté run
méthode comme par Maxim réponse. Encore besoin de trouver un moyen d'attendre jusqu'à $http
appel renvoie avant d'aller de l'avant avec les contrôleurs.
//Some initializing code before Angular invokes controllers
myApp.run(['$rootScope','$http', '$q', function($rootScope, $http, $q) {
return GetSession($http, $q);
}]);
function GetSession($http, $q){
var defer = $q.defer();
$http({
url: GetSessionTokenWebMethod,
method: "POST",
data: "{}",
headers: { 'Content-Type': 'application/json' }
}).success(function (data, status, headers, config) {
GlobalSessionToken = data;
defer.resolve('done');
}).error(function (data, status, headers, config) {
console.log(data);
defer.reject();
});
return defer.promise;
}
source d'informationauteur Pawan Pillai | 2014-02-03
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas reporter l'initialisation des contrôleurs.
Vous pouvez mettre votre contrôleur de code à l'intérieur d'une Session promesse de rappel:
Alternative: Si vous ne voulez pas utiliser ces rappels, vous pourriez avoir votre demande de session synchrone, mais ce serait une chose terrible à faire.
Même si certaines des solutions proposées ici sont parfaitement valides,
resolve
propriété des routes définition est la voie à suivre, à mon avis. La rédaction de votre application logique à l'intérieursession.then
dans chaque contrôleur est un peu trop , nous sommes habitués à une telle approche trop dans l'un des projets et je ne fonctionne pas si bien.Le moyen le plus efficace consiste à retarder le contrôleur de l'instanciation avec
resolve
car c'est une solution intégrée. Le seul problème est que vous devez ajouterresolve
propriété avec le même code pour chaque définition de la route, ce qui conduit à la duplication de code.Pour résoudre ce problème, vous pouvez modifier votre itinéraire définition des objets dans une fonction d'assistance comme ceci:
Et puis, où définir vos itinéraires comme ceci:
C'est l'une des nombreuses solutions que j'ai essayé et j'ai aimé le plus, car il est propre et SÈCHE.
Vous n'avez pas fourni tous les détails liés à GetSession. Pour les scénarios comme cela, vous devez utiliser le
resolve
propriété tout en définissant vos itinéraires en$routeProvider
. Je vois que vous êtes en utilisantresolve
déjà.Ce que vous pouvez faire maintenant est d'envelopper le
GlobalSessionToken
dans un Angulaire de service commeGlobalSessionTokenService
et de l'appeler dans la résoudre pour obtenir le jeton avant la route des charges. CommeCela peut ensuite être injecté dans votre contrôleur avec
controllers.MasterController = function($rootScope, $http,GlobalSessionToken){