带有 UI.Router 的 AngularJS 标签 [英] AngularJS Tabs with UI.Router
问题描述
我有一个单页应用程序,左侧有垂直表格.我可以单击每个选项卡并显示预期的内容.我遇到的问题是我无法以编程方式将所选选项卡的 ng-checked 更改为true",将未选择的选项卡更改为false".因此,所选选项卡始终位于选项卡列表中的第一个选项卡上.我已经提供了运行这个应用程序的所有代码(6 个文件),所以你可以看到我在说什么
Index.html
<头><title>OneilAndK</title><meta http-equiv="content-type" content="text/html; charset=UTF-8" ><meta name="viewport" content="width=device-width, initial-scale=1.0"><link href="css/uxcore.css" rel="样式表"><script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script><script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script><script src="routing.js"></script><link rel="stylesheet" href="verticalTab.css" rel="stylesheet"/>头部><身体><div class="tabordion"><input type="radio" name="sections" id="option1" ng-checked = true ><label ui-sref="About" for="option1">关于</label><文章><div ui-view></div></文章></节><input type="radio" name="sections" id="option2" ng-checked = false ><label ui-sref="Knowledge" for="option2" >Knowledge</label><文章><div ui-view></div></文章></节><input type="radio" name="sections" id="option3" ng-checked = false ><label ui-sref="Contact" for="option3" >Contact</label><文章><div ui-view></div></文章></节>
</html>
关于.html
<p >这是我的关于页面</p>
Contact.html
<p >这是我的联系方式页面</p>
Knowledge.html
<p >这是我的知识页面</p>
routing.js
var app = angular.module('mainApp', ['ui.router']);app.config(['$stateProvider','$urlRouterProvider', function($stateProvider,$urlRouterProvider){$urlRouterProvider.otherwise("Home.html")$stateProvider.state('Contact', {url:"/Contact",templateUrl:"Contact.html"}).state('Knowledge', {url:"/Knowledge",templateUrl:"Knowledge.html"}).state('About', {url:"/About",templateUrl:"About.html"})}]);
verticalTab.css
h1 {颜色:#333;字体系列:arial、sans-serif;保证金:1em 自动;宽度:80%;}.tabordion {颜色:#333;显示:块;字体系列:arial、sans-serif;保证金:自动;位置:相对;宽度:80%;}.tabordion 输入[名称=部分"] {左:-9999px;位置:绝对;顶部:-9999px;}.tabordion 部分 {显示:块;}.tabordion 部分标签 {背景:#ccc;边框:1px 实心 #fff;光标:指针;显示:块;字体大小:1.2em;字体粗细:粗体;填充:15px 20px;位置:相对;宽度:180px;z-索引:100;}.tabordion 部分文章 {显示:无;左:230px;最小宽度:300px;填充:0 0 0 21px;位置:绝对;顶部:0;}.tabordion 部分文章:{背景颜色:#ccc;底部:0;内容: "";显示:块;左:-229px;位置:绝对;顶部:0;宽度:220px;z-索引:1;}.tabordion input[name="sections"]:checked + label {背景:#eee;颜色:#bbb;}.tabordion input[name="sections"]:checked ~ article {显示:块;}@media(最大宽度:533px){h1{宽度:100%;}.tabordion {宽度:100%;}.tabordion 部分标签 {字体大小:1em;宽度:160px;}.tabordion 部分文章 {左:200px;最小宽度:270px;}.tabordion 部分文章:{背景颜色:#ccc;底部:0;内容: "";显示:块;左:-199px;位置:绝对;顶部:0;宽度:200px;}}@media(最大宽度:768px){h1{宽度:96%;}.tabordion {宽度:96%;}}@media(最小宽度:1366px){h1{宽度:70%;}.tabordion {宽度:70%;}}
我会使用 angular-ui-bootstrap
来创建选项卡面板.为了动态生成标签标题,您可以使用 stateHelper
模块.
使用 stateHelper
,您可以创建一个配置对象,您也可以在 ng-repeat
中使用该对象来生成选项卡面板的导航栏.
让它工作的唯一棘手的事情是 $stateChangeStart
监听器来计算活动路由的索引.找到索引后,它将通过 $rootScope.active
变量传递给 ui-bootstrap
.
请看下面的演示或这个 jsfiddle.
angular.module('demoApp', ['ui.router', 'ui.bootstrap', 'ui.router.stateHelper']).run(['$state', '$rootScope', 'TABS_CONFIG', function($state, $rootScope, TABS_CONFIG) {//运行需要在加载时设置正确的标签索引var tabs = TABS_CONFIG.children;$rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) {angular.forEach(tabs, function(item, index) {if (item.name == toState.name) {$rootScope.active = 索引;}});});}]).constant('TABS_CONFIG', {名称:'标签',templateUrl: 'tabs.html',摘要:真实,孩子们: [{网址:'/关于',name: '关于',模板:'<div class="container"><h1>about</h1></div>'//templateUrl: 'about.html'}, {网址:'/联系',name: '联系人',模板:'<div class="container"><h1>contact</h1></div>'//templateUrl: 'contact.html'}, {网址:'/诀窍',name: '诀窍',模板:'<div class="container"><h1>knowhow</h1></div>'//templateUrl: 'knowhow.html'},]}).controller('mainController', function($scope, $state, TABS_CONFIG) {$scope.tabs = TABS_CONFIG.children;$scope.go = 函数(标签){//$scope.active = $scope.tabs.indexOf(tab);$state.go(tab.name);};}).config(路由);功能路线($ urlRouterProvider,stateHelperProvider,TABS_CONFIG){$urlRouterProvider.otherwise('/contact');stateHelperProvider.state(TABS_CONFIG, {keepOriginalNames: 真});}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="样式表"/><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap-tpls.min.js"></script><script src="https://cdn.rawgit.com/marklagendijk/ui-router.stateHelper/master/statehelper.js"></script><div ng-app="demoApp" ng-controller="mainController"><div ui-view></div><script type="text/ng-template" id="tabs.html"><uib-tabset active="active"><uib-tab index="$index" ng-repeat="tab 中的tab" ng-click="go(tab)"><uib-tab-heading>{{tab.name}}</uib-tab-heading><div ui-view></div></uib-tab></uib-tabset>
I have a single page app with vertical tables to the left. I'm able to to click on each tab and the expected content is showing. The problem I'm having is I'm not able to programmatically change the ng-checked to "true" for the selected tab and "false" for the unselected tab. Because of this the selected tab is always on the first tab in the list of tabs. I've provided all the codes (6 files) to run this app so you can see what im talking about
Index.html
<html ng-app= "mainApp">
<head>
<title>OneilAndK</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" >
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/uxcore.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<script src="routing.js"></script>
<link rel="stylesheet" href="verticalTab.css" rel="stylesheet"/>
</head>
<body>
<div class="tabordion">
<section id="section1">
<input type="radio" name="sections" id="option1" ng-checked = true >
<label ui-sref="About" for="option1">About</label>
<article>
<div ui-view></div>
</article>
</section>
<section id="section2">
<input type="radio" name="sections" id="option2" ng-checked = false >
<label ui-sref="Knowledge" for="option2" >Knowledge</label>
<article>
<div ui-view></div>
</article>
</section>
<section id="section3">
<input type="radio" name="sections" id="option3" ng-checked = false >
<label ui-sref="Contact" for="option3" >Contact</label>
<article>
<div ui-view></div>
</article>
</section>
</div>
</body>
</html>
About.html
<p >This is my about page</p>
Contact.html
<p >This is my Contact page</p>
Knowledge.html
<p >This is my knowledge page</p>
routing.js
var app = angular.module('mainApp', ['ui.router']);
app.config(['$stateProvider','$urlRouterProvider', function($stateProvider,$urlRouterProvider){
$urlRouterProvider.otherwise("Home.html")
$stateProvider
.state('Contact', {url:"/Contact",templateUrl:"Contact.html"})
.state('Knowledge', {url:"/Knowledge",templateUrl:"Knowledge.html"})
.state('About', {url:"/About",templateUrl:"About.html"})
}]);
verticalTab.css
h1 {
color: #333;
font-family: arial, sans-serif;
margin: 1em auto;
width: 80%;
}
.tabordion {
color: #333;
display: block;
font-family: arial, sans-serif;
margin: auto;
position: relative;
width: 80%;
}
.tabordion input[name="sections"] {
left: -9999px;
position: absolute;
top: -9999px;
}
.tabordion section {
display: block;
}
.tabordion section label {
background: #ccc;
border:1px solid #fff;
cursor: pointer;
display: block;
font-size: 1.2em;
font-weight: bold;
padding: 15px 20px;
position: relative;
width: 180px;
z-index:100;
}
.tabordion section article {
display: none;
left: 230px;
min-width: 300px;
padding: 0 0 0 21px;
position: absolute;
top: 0;
}
.tabordion section article:after {
background-color: #ccc;
bottom: 0;
content: "";
display: block;
left:-229px;
position: absolute;
top: 0;
width: 220px;
z-index:1;
}
.tabordion input[name="sections"]:checked + label {
background: #eee;
color: #bbb;
}
.tabordion input[name="sections"]:checked ~ article {
display: block;
}
@media (max-width: 533px) {
h1 {
width: 100%;
}
.tabordion {
width: 100%;
}
.tabordion section label {
font-size: 1em;
width: 160px;
}
.tabordion section article {
left: 200px;
min-width: 270px;
}
.tabordion section article:after {
background-color: #ccc;
bottom: 0;
content: "";
display: block;
left:-199px;
position: absolute;
top: 0;
width: 200px;
}
}
@media (max-width: 768px) {
h1 {
width: 96%;
}
.tabordion {
width: 96%;
}
}
@media (min-width: 1366px) {
h1 {
width: 70%;
}
.tabordion {
width: 70%;
}
}
I would use angular-ui-bootstrap
to create tab panels. And for dynamically generating the tab headings you can use stateHelper
module.
With stateHelper
you can create a configuration object that you can also use inside a ng-repeat
to generate the navbar of the tab panel.
The only tricky thing to make it work is the $stateChangeStart
listener to calculate the index for the active route. Once the index is found it will be passed to ui-bootstrap
via $rootScope.active
variable.
Please have a look at the demo below or this jsfiddle.
angular.module('demoApp', ['ui.router', 'ui.bootstrap', 'ui.router.stateHelper'])
.run(['$state', '$rootScope', 'TABS_CONFIG', function($state, $rootScope, TABS_CONFIG) {
// run needed to set the correct tab-index on load
var tabs = TABS_CONFIG.children;
$rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) {
angular.forEach(tabs, function(item, index) {
if (item.name == toState.name) {
$rootScope.active = index;
}
});
});
}])
.constant('TABS_CONFIG', {
name: 'tabs',
templateUrl: 'tabs.html',
abstract: true,
children: [{
url: '/about',
name: 'about',
template: '<div class="container"><h1>about</h1></div>'
//templateUrl: 'about.html'
}, {
url: '/contact',
name: 'contact',
template: '<div class="container"><h1>contact</h1></div>'
//templateUrl: 'contact.html'
}, {
url: '/knowhow',
name: 'know-how',
template: '<div class="container"><h1>knowhow</h1></div>'
//templateUrl: 'knowhow.html'
},
]
})
.controller('mainController', function($scope, $state, TABS_CONFIG) {
$scope.tabs = TABS_CONFIG.children;
$scope.go = function(tab) {
//$scope.active = $scope.tabs.indexOf(tab);
$state.go(tab.name);
};
})
.config(routes);
function routes($urlRouterProvider, stateHelperProvider, TABS_CONFIG) {
$urlRouterProvider.otherwise('/contact');
stateHelperProvider.state(TABS_CONFIG, {
keepOriginalNames: true
});
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.2/ui-bootstrap-tpls.min.js"></script>
<script src="https://cdn.rawgit.com/marklagendijk/ui-router.stateHelper/master/statehelper.js"></script>
<div ng-app="demoApp" ng-controller="mainController">
<div ui-view></div>
<script type="text/ng-template" id="tabs.html">
<uib-tabset active="active">
<uib-tab index="$index" ng-repeat="tab in tabs" ng-click="go(tab)">
<uib-tab-heading>{{tab.name}}</uib-tab-heading>
<div ui-view></div>
</uib-tab>
</uib-tabset>
</script>
</div>
这篇关于带有 UI.Router 的 AngularJS 标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!