AngularJS Tabs with UI.Router

吃可爱长大的小学妹 提交于 2019-12-12 03:28:41

问题


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%;
  }
}

回答1:


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>


来源:https://stackoverflow.com/questions/36971536/angularjs-tabs-with-ui-router

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!