UNPKG

ionic-angular

Version:

[![Circle CI](https://circleci.com/gh/driftyco/ionic.svg?style=svg)](https://circleci.com/gh/driftyco/ionic)

120 lines (110 loc) 4.24 kB
/** * @ngdoc directive * @name ionTabs * @module ionic * @delegate ionic.service:$ionicTabsDelegate * @restrict E * @codepen odqCz * * @description * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed * through. * * Assign any [tabs class](/docs/components#tabs) to the element to define * its look and feel. * * For iOS, tabs will appear at the bottom of the screen. For Android, tabs will be at the top * of the screen, below the nav-bar. This follows each OS's design specification, but can be * configured with the {@link ionic.provider:$ionicConfigProvider}. * * See the {@link ionic.directive:ionTab} directive's documentation for more details on * individual tabs. * * Note: do not place ion-tabs inside of an ion-content element; it has been known to cause a * certain CSS bug. * * @usage * ```html * <ion-tabs class="tabs-positive tabs-icon-top"> * * <ion-tab title="Home" icon-on="ion-ios-filing" icon-off="ion-ios-filing-outline"> * <!-- Tab 1 content --> * </ion-tab> * * <ion-tab title="About" icon-on="ion-ios-clock" icon-off="ion-ios-clock-outline"> * <!-- Tab 2 content --> * </ion-tab> * * <ion-tab title="Settings" icon-on="ion-ios-gear" icon-off="ion-ios-gear-outline"> * <!-- Tab 3 content --> * </ion-tab> * * </ion-tabs> * ``` * * @param {string=} delegate-handle The handle used to identify these tabs * with {@link ionic.service:$ionicTabsDelegate}. */ IonicModule .directive('ionTabs', [ '$ionicTabsDelegate', '$ionicConfig', function($ionicTabsDelegate, $ionicConfig) { return { restrict: 'E', scope: true, controller: '$ionicTabs', compile: function(tElement) { //We cannot use regular transclude here because it breaks element.data() //inheritance on compile var innerElement = jqLite('<div class="tab-nav tabs">'); innerElement.append(tElement.contents()); tElement.append(innerElement) .addClass('tabs-' + $ionicConfig.tabs.position() + ' tabs-' + $ionicConfig.tabs.style()); return { pre: prelink, post: postLink }; function prelink($scope, $element, $attr, tabsCtrl) { var deregisterInstance = $ionicTabsDelegate._registerInstance( tabsCtrl, $attr.delegateHandle, tabsCtrl.hasActiveScope ); tabsCtrl.$scope = $scope; tabsCtrl.$element = $element; tabsCtrl.$tabsElement = jqLite($element[0].querySelector('.tabs')); $scope.$watch(function() { return $element[0].className; }, function(value) { var isTabsTop = value.indexOf('tabs-top') !== -1; var isHidden = value.indexOf('tabs-item-hide') !== -1; $scope.$hasTabs = !isTabsTop && !isHidden; $scope.$hasTabsTop = isTabsTop && !isHidden; $scope.$emit('$ionicTabs.top', $scope.$hasTabsTop); }); function emitLifecycleEvent(ev, data) { ev.stopPropagation(); var previousSelectedTab = tabsCtrl.previousSelectedTab(); if (previousSelectedTab) { previousSelectedTab.$broadcast(ev.name.replace('NavView', 'Tabs'), data); } } $scope.$on('$ionicNavView.beforeLeave', emitLifecycleEvent); $scope.$on('$ionicNavView.afterLeave', emitLifecycleEvent); $scope.$on('$ionicNavView.leave', emitLifecycleEvent); $scope.$on('$destroy', function() { // variable to inform child tabs that they're all being blown away // used so that while destorying an individual tab, each one // doesn't select the next tab as the active one, which causes unnecessary // loading of tab views when each will eventually all go away anyway $scope.$tabsDestroy = true; deregisterInstance(); tabsCtrl.$tabsElement = tabsCtrl.$element = tabsCtrl.$scope = innerElement = null; delete $scope.$hasTabs; delete $scope.$hasTabsTop; }); } function postLink($scope, $element, $attr, tabsCtrl) { if (!tabsCtrl.selectedTab()) { // all the tabs have been added // but one hasn't been selected yet tabsCtrl.select(0); } } } }; }]);