[英]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.