Подтвердить что ты не робот

Динамический класс корпуса с интерфейсом Angular UI-Router

Я пытаюсь найти элегантный способ иметь настраиваемый динамический класс тега body, который я могу легко установить из ui-router configurations, и если ни один не установлен, я могу использовать значение по умолчанию или нет.

Пример:

routes.js

$stateProvider
      .state('login', {
           url: "/login",
           template: 'Login'
      })
      .state('register', {
           url: "/register",
           template: 'Register'
      }).
      .state('profile', {
           url: "/profile",
           template: 'Profile'
      });;

Простая разметка HTML

<html>
   <body class=""> <!-- Dynamically class to change -->
      <div ui-view></div>
   </body>
</html>

Сценарий:

1 - Посещение state входа. Я должен иметь класс тела, равный auth

2 - Посещая регистр state , он будет иметь тот же класс auth

3 - При посещении профиля state тело будет иметь класс по умолчанию или none

Как вы это достигаете?

4b9b3361

Ответ 1

У вас может быть мастер AppController, который контролирует это:

<html ng-app="app" ng-controller="AppController as appController">
...
<body class="{{ appController.bodyClasses }}">

Внутри 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';
});

Внутри вашего маршрута defs:

  .state('register', {
       url: "/register",
       template: 'Register',
       data: {
           bodyClasses: 'auth'
       }
  });

Подробнее об этой стратегии атрибутов данных см. Документация UI Router.

Ответ 2

Здесь аналогичный подход, как @jmq, используя данные состояния, но реализованный как директива вместо контроллера. (Самое приятное в директиве - вы можете применить это к любым произвольным элементам)

Пример разметки

<body ng-app="app" route-css-classnames>

Конфигурация маршрутов (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'
  });

Директива (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);
                        }
                    }
                });
            }
        }
    }
}());

Ответ 3

Вы также можете применить это на свой тег тела или там, где вам это нужно.

ng-class="$state.current.name"