簡體   English   中英

具有Angular UI-Router的動態body類

[英]Dynamic body class with Angular UI-Router

我正在嘗試找到一種優雅的方法,可以從ui-router configurations輕松設置body標簽的自定義動態類,如果沒有設置,我可以使用默認選項或無。

例:

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 配置文件時 ,正文將具有默認類或

你是如何實現這一目標的?

你可以有一個控制它的主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路由器文檔

這是與@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);
                        }
                    }
                });
            }
        }
    }
}());

您也可以將此應用於您的身體標簽或您需要的任何地方。

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

這只是使用ui-router@1.x轉換鈎子的@ JeremyWeir指令的一個版本。

import angular from 'angular';

class RouteCssClassNamesDirective {
  constructor($transitions) {
    this.$transitions = $transitions;
    this.restrict = 'A';
  }

  link(scope, element, attrs) {
    this.$transitions.onSuccess({}, (trans) => {
      const fromClassNames = angular.isDefined(trans.from().data) && angular.isDefined(trans.from().data.cssClassNames) ? trans.from().data.cssClassNames : null;
      const toClassNames = angular.isDefined(trans.to().data) && angular.isDefined(trans.to().data.cssClassNames) ? trans.to().data.cssClassNames : null;
      if (fromClassNames !== toClassNames) {
        if (fromClassNames) {
          element.removeClass(fromClassNames);
        }
        if (toClassNames) {
          element.addClass(toClassNames);
        }
      }
    });
  }

  static create() {
    return new RouteCssClassNamesDirective(...arguments);
  }

}

RouteCssClassNamesDirective.create.$inject = ['$transitions'];

export default angular.module('shared')
  .directive('routeCssClassNames', RouteCssClassNamesDirective.create);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM