Reputation: 447
When I choose a tab, I want the url to change. should I create a state for each tab ?
This is my code which works fine without changing the state .
My app.js
var myApp=angular.module('app', ['ui.router','ngAnimate', 'ui.bootstrap']);
myApp.config([
'$stateProvider',
'$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider.state('/', {
url: "",
views: {
"ratios": { templateUrl: "views/requetes.html" },
"reqBase": {templateUrl: "views/common.html" },
"SQLconsole": {templateUrl: "views/console.html" },
}
});
$urlRouterProvider.otherwise('/');
}]);
myApp.controller('TabsCtrl', function ($rootScope, $state, $scope, $window) {
$scope.tabs = [
{ title: "ratios", route: "ratios", active: true },
{ title: "requetes de Base", route: "reqBase", active: false },
{ title: "Console", route: "SQLconsole", active: false },
];
});
Tabset definition:
<div data-ng-controller="TabsCtrl">
<uib-tabset>
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disable="tab.disabled">
<div ui-view="{{tab.route}}"></div>
</uib-tab>
</uib-tabset>
</div>
Upvotes: 3
Views: 11761
Reputation: 1360
As mentioned above, I recommend checking out a blog post I made previously regarding this topic.
https://long2know.com/2016/01/angular-tabbed-navigation/
I detail managing state, intercepting state, preventing navigation (conditionally), etc. It's driven by services and promises that make creating navigation workflow easy and robust.
If you prefer to not follow the link to my blog, here's a plunker:
https://embed.plnkr.co/w5xdJP?autoCloseSidebar&show=preview
And here's the basic config:
myApp.config(['$uibModalProvider', '$locationProvider', '$stateProvider', '$urlRouterProvider',
function ($uibModalProvider, $locationProvider, $stateProvider, $urlRouterProvider) {
$uibModalProvider.options = { animation: true, backdrop: 'static', keyboard: false };
$locationProvider.html5Mode(false);
$urlRouterProvider
.when('/', '/state1')
.otherwise("/state1");
$stateProvider
.state('tabs', {
abstract: true,
url: '/',
views: {
'tabs': {
controller: 'tabsCtrl as tc',
templateUrl: 'tabs.html',
}
}
})
.state('tabs.state1', {
url: 'state1',
templateUrl: 'state1.html',
controller: function () { },
reloadOnSearch: false
})
.state('tabs.state2', {
url: 'state2',
templateUrl: 'state2.html',
controller: function () { },
reloadOnSearch: false
})
.state('tabs.state3', {
url: 'state3',
templateUrl: 'state3.html',
controller: function () { },
reloadOnSearch: false
})
.state('tabs.state4', {
url: 'state4',
templateUrl: 'state4.html',
controller: function () { },
reloadOnSearch: false
})
}]);
myApp.run(['$log', 'navigationService', function ($log, navigationService) {
// Note, we need a reference to the navigationService so $state events are tracked.
$log.log("Start.");
}]);
However, I usually create a service that contains a list of the states that I will bind to the tabs:
var appStates = function ($state) {
var
states = [
{ name: 'state1', heading: "Tab 1", route: "tabs.state1", active: false, isVisible: true, href: $state.href("tabs.state1") },
{ name: 'state2', heading: "Tab 2", route: "tabs.state2", active: false, isVisible: true, href: $state.href("tabs.state2") },
{ name: 'state3', heading: "Tab 3", route: "tabs.state3", active: false, isVisible: true, href: $state.href("tabs.state3") },
{ name: 'state4', heading: "Tab 4", route: "tabs.state4", active: false, isVisible: true, href: $state.href("tabs.state4") }
];
return {
states: states
};
};
appStates.$inject = ['$state'];
angular.module('long2know.services')
.factory('appStates', appStates);
The HTML looks like this:
<script type="text/ng-template" id="tabs.html">
<div class="row">
<uib-tabset>
<uib-tab ng-repeat="tab in tc.appStates" heading="{{tab.heading}}" active="tab.active" disable="tab.disabled"
select="tc.tabSelected(tab.route)">
</uib-tab>
</uib-tabset>
</div>
<div id="tabs-views" data-ui-view></div>
</script>
The tabController:
var tabsCtrl = function ($state, $location, $filter, appStates, navigationService) {
var
vm = this,
initialize = function () {
vm.appStates = appStates.states;
};
vm.tabSelected = function (route) {
$state.go(route);
};
initialize();
};
tabsCtrl.$inject = ['$state', '$location', '$filter', 'appStates', 'navigationService'];
angular
.module('long2know.controllers')
.controller('tabsCtrl', tabsCtrl);
Upvotes: 3
Reputation: 6770
Try this code :
var myApp=angular.module('app', ['ui.router','ngAnimate', 'ui.bootstrap']);
myApp.config([
'$stateProvider',
'$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url:"/",
templateUrl: "views/requetes.html",
})
.state('home.ratios', {
url:"/ratios",
templateUrl: "views/requetes.html",
})
.state('home.reqBase', {
url:"/reqBase",
templateUrl: "views/common.html",
})
.state('home.SQLconsole', {
url:"/SQLconsole",
templateUrl: "views/console.html"
})
$urlRouterProvider.otherwise('/');
}]);
Here is the working PLUNKR for this code !!
Upvotes: 5
Reputation: 996
Yes you should use nested states for your tabs. Something like below:
$stateProvider
.state('main', {
url: '/',
templateUrl: 'main.html'
})
.state('main.ratios', {
url: '/ratios',
templateUrl: 'views/requetes.html'
})
Here is a similar implementation with a navbar that you can use as an example.
Upvotes: 0