J'écris un gestionnaire pour $stateChangeStart
:
var stateChangeStartHandler = function(e, toState, toParams, fromState, fromParams) {
if (toState.includes('internal') && !$cookies.MySession) {
e.preventDefault();
// Some login stuff.
}
};
$rootScope.$on('$stateChangeStart', stateChangeStartHandler);
toState
n'a pas la méthode includes. Devrais-je faire quelque chose de différent ou y a-t-il un moyen de faire ce que j'essaie de faire?
En outre, lorsque // certains éléments de connexion incluent un $state.go(...)
, je reçois une boucle infinie. Qu'est-ce qui pourrait causer ça?
Voici un exemple plus complet démontrant ce que nous avons finalement mis au travail:
angular.module('test', ['ui.router', 'ngCookies'])
.config(['$stateProvider', '$cookiesProvider', function($stateProvider, $cookiesProvider) {
$stateProvider
.state('public', {
abstract: true
})
.state('public.login', {
url: '/login'
})
.state('tool', {
abstract: true
})
.state('tool.suggestions', {
url: '/suggestions'
});
}])
.run(['$state', '$cookies', '$rootScope', function($state, $cookies, $rootScope) {
$rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) {
if (toState.name.indexOf('tool') > -1 && !$cookies.Session) {
// If logged out and transitioning to a logged in page:
e.preventDefault();
$state.go('public.login');
} else if (toState.name.indexOf('public') > -1 && $cookies.Session) {
// If logged in and transitioning to a logged out page:
e.preventDefault();
$state.go('tool.suggestions');
};
});
});
Je n'aime pas utiliser indexOf
pour rechercher un état particulier dans le toState
. C'est naïf. Je ne sais pas pourquoi toState
et fromState
ne pourraient pas être une instance du service $state
, Ni pourquoi le service $state
Ne pouvait pas accepter remplacement de configuration d'état dans ses méthodes.
La boucle infinie a été causée par une erreur de notre part. Je n'aime pas cela, alors je cherche toujours de meilleures réponses.
Lorsque vous ajoutez un objet à $stateProvider.state
cet objet est ensuite passé avec l'état. Vous pouvez donc ajouter des propriétés supplémentaires que vous pourrez lire plus tard, si nécessaire.
Exemple de configuration de route
$stateProvider
.state('public', {
abstract: true,
module: 'public'
})
.state('public.login', {
url: '/login',
module: 'public'
})
.state('tool', {
abstract: true,
module: 'private'
})
.state('tool.suggestions', {
url: '/suggestions',
module: 'private'
});
Le $stateChangeStart
événement vous donne accès aux objets toState
et fromState
. Ces objets d'état contiendront les propriétés de configuration.
Exemple de contrôle pour la propriété du module personnalisé
$rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) {
if (toState.module === 'private' && !$cookies.Session) {
// If logged out and transitioning to a logged in page:
e.preventDefault();
$state.go('public.login');
} else if (toState.module === 'public' && $cookies.Session) {
// If logged in and transitioning to a logged out page:
e.preventDefault();
$state.go('tool.suggestions');
};
});
Je n'ai pas changé la logique des cookies parce que je pense que cela dépasse la portée de votre question.
Vous pouvez créer un assistant pour vous permettre de travailler de manière plus modulaire.
Valeur publicStates
myApp.value('publicStates', function(){
return {
module: 'public',
routes: [{
name: 'login',
config: {
url: '/login'
}
}]
};
});
Valeur privateStates
myApp.value('privateStates', function(){
return {
module: 'private',
routes: [{
name: 'suggestions',
config: {
url: '/suggestions'
}
}]
};
});
L'aide
myApp.provider('stateshelperConfig', function () {
this.config = {
// These are the properties we need to set
// $stateProvider: undefined
process: function (stateConfigs){
var module = stateConfigs.module;
$stateProvider = this.$stateProvider;
$stateProvider.state(module, {
abstract: true,
module: module
});
angular.forEach(stateConfigs, function (route){
route.config.module = module;
$stateProvider.state(module + route.name, route.config);
});
}
};
this.$get = function () {
return {
config: this.config
};
};
});
Vous pouvez maintenant utiliser l'assistant pour ajouter la configuration d'état à votre configuration d'état.
myApp.config(['$stateProvider', '$urlRouterProvider',
'stateshelperConfigProvider', 'publicStates', 'privateStates',
function ($stateProvider, $urlRouterProvider, helper, publicStates, privateStates) {
helper.config.$stateProvider = $stateProvider;
helper.process(publicStates);
helper.process(privateStates);
}]);
De cette façon, vous pouvez résumer le code répété et proposer une solution plus modulaire.
Note: le code ci-dessus n'est pas testé