Separate controller per tab in angular-material w/ ui-router
If you name your ui-view elements (e.g. <div ui-view="player"></div>
) then you can target them in your $stateProvider config.
So, given the following markup in template.html:
<md-tabs md-selected="currentTab"> <md-tab label="Player" ui-sref="tabs.player"> <div ui-view="player"></div> </md-tab> <md-tab label="Map" ui-sref="tabs.map"> <div ui-view="map"></div> </md-tab></md-tabs>
You could target each ui-view
element (and update the currentTab index) with the following $stateProvider config:
.state('tabs', { abstract: true, url: '/tabs', templateUrl: 'template.html', controller: function($scope) { $scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { $scope.currentTab = toState.data.selectedTab; }); } }).state('tabs.player', { url: '/player', data: { 'selectedTab': 0 }, views: { 'player': { controller: playerController } } }).state('tabs.map', { url: '/map', data: { 'selectedTab': 1 }, views: { 'map': { controller: mapController } } })
All you need to do now is define playerController and mapController. You can still load partial templates etc. into the ui-view
, see the section on Multiple Named Views.
I was able to get this going by just doing
index.html
<md-toolbar ng-controller="NavigationController as vm" ng-include="'app/components/navbar/navbar.html'" class="md-default-theme" ></md-toolbar><md-content ui-view md-scroll-y class="md-default-theme" role="main" flex></md-content>
navbar.html
<md-tabs md-selected="vm.currentTab" md-stretch-tabs="always" class="main-toolbar"> <md-tab label="Home" ui-sref="home"></md-tab> <md-tab label="Portfolio" ui-sref="portfolio"></md-tab> <md-tab label="Contact" ui-sref="contact"></md-tab></md-tabs>
app.js
$stateProvider .state('home', { url: '/', data: { 'selectedTab' : 0 }, templateUrl: 'app/components/main/main.html', controller: 'MainController as vm' }) .state('portfolio', { url: '/portfolio', data: { 'selectedTab' : 1 }, templateUrl: 'app/components/portfolio/portfolio.html', controller: 'PortfolioController as vm' }) .state('contact', { url: '/contact', data: { 'selectedTab' : 2 }, templateUrl: 'app/components/contact/contact.html', controller: 'ContactController as vm' });
navigation.controller.js
function NavigationController($scope) { var vm = this; $scope.$on('$stateChangeSuccess', function(event, toState) { vm.currentTab = toState.data.selectedTab; });}
For anyone coming from google and not using ui-router, you can do the same thing with the default ng-router:In your index file place the tabs code:
<md-tabs md-selected="0" ng-controller="TabCtrl"> <md-tab ng-repeat="tab in tabs" md-on-select="switchTab($index)" label="{{tab}}"> <div ng-view></div> </md-tab></md-tabs>
Then create TabCtrl:
// Define the titles of your tabs$scope.tabs = ["Player", "Map"];// Change the tab$scope.switchTab = function(index) { switch(index) { case 0: $location.path('/player');break; case 1: $location.path('/map');break; }}
Finally define your routes in your config:
.when( '/player', { templateUrl: 'partials/player.html', controller: 'PlayerCtrl'}).when( '/map', { templateUrl: 'partials/map.html', controller: 'MapCtrl'});