J'essaie de trouver une façon élégante d'avoir une classe dynamique personnalisée de la balise de corps que je peux régler facilement à partir des ui-router configurations
et si aucune n'est définie, je peux utiliser une option par défaut ou aucune.
Exemple:
Routes.js
$stateProvider .state('login', { url: "/login", template: 'Login' }) .state('register', { url: "/register", template: 'Register' }). .state('profile', { url: "/profile", template: 'Profile' });;
Marquage simplifié HTML
<html> <body class=""> <!-- Dynamically class to change --> <div ui-view></div> </body> </html>
Scénario:
1 – Visiter l' state
connexion Je devrais que la classe du corps soit égale à auth
2 – En visitant le registre d' state
à ce stade, il aura la même classe d' auth
3 – En visitant le profil d' state
, le corps aura la classe par défaut ou aucun
Comment parviens-tu cela?
Vous pouvez avoir un AppController principal qui contrôle ceci:
<html ng-app="app" ng-controller="AppController as appController"> ... <body class="{{ appController.bodyClasses }}">
Inside AppController:
var vm = this; vm.bodyClasses = 'default'; // this'll be called on every state change in the app $scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ if (angular.isDefined(toState.data.bodyClasses)) { vm.bodyClasses = toState.data.bodyClasses; return; } vm.bodyClasses = 'default'; });
À l'intérieur de votre parcours:
.state('register', { url: "/register", template: 'Register', data: { bodyClasses: 'auth' } });
Consultez la documentation de UI Router pour en savoir plus sur cette stratégie d'attributs de données.
Voici une approche similaire à laquelle @ jmq utilise les données d'état, mais implémentée comme une directive au lieu d'un contrôleur. (La bonne chose à propos de la directive est que vous pouvez appliquer cela à des éléments arbitraires)
Exemple de balisage
<body ng-app="app" route-css-classnames>
Routes Config (routes.js)
$stateProvider .state('login', { url: "/login", template: 'Login', data : { cssClassnames : 'auth' } }) .state('register', { url: "/register", template: 'Register', data : { cssClassnames : 'auth' } }). .state('profile', { url: "/profile", template: 'Profile' });
Directive (routeCssClassnames.js)
(function () { 'use strict'; angular.module('shared').directive('routeCssClassnames', routeCssClassnames); function routeCssClassnames($rootScope) { return { restrict: 'A', scope: {}, link: function (scope, elem, attr, ctrl) { $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { var fromClassnames = angular.isDefined(fromState.data) && angular.isDefined(fromState.data.cssClassnames) ? fromState.data.cssClassnames : null; var toClassnames = angular.isDefined(toState.data) && angular.isDefined(toState.data.cssClassnames) ? toState.data.cssClassnames : null; // don't do anything if they are the same if (fromClassnames != toClassnames) { if (fromClassnames) { elem.removeClass(fromClassnames); } if (toClassnames) { elem.addClass(toClassnames); } } }); } } } }());
Vous pouvez également l'appliquer sur votre étiquette de corps ou partout où vous en avez besoin.
ng-class="$state.current.name"