Switch tab in controller

spent some time on try and error, I found out there is a controller array in $scope, and there is a tabsController inside.

Here is how I switch tab in ionic from angular controller.

$scope.controllers[0].tabsController.select(1);

I tried the following and all works:

$scope.controllers[0].tabsController.select(1);
$scope.controllers[1].tabsController.select(1);
$scope.controllers[2].tabsController.select(1);
1 Like

Couldn’t find enough information on how the scope and controller data structure.
I think it would be great if the ionic angular framework talks more about what controllers are available inside the $scope, and also the available methods in different type of controllers

1 Like

Agreed. Having Ionic out for the last week has really helped us realize how we should adjust the docs and help make it more clear how to do things like this.

Do you have any thoughts on an API for switching tabs that you would prefer? Or maybe we could just make this process more clear, or make it easier to modify the controller from the tabs controller rather than the child tabs.

To align with the current documentation, it uses the keyword controller, i.e. Tab Bar Controller

I would expect

$scope.tabBarControllers

always return me the array of Tab Bar Controller in scope (empty array if there is none)

To find a specific Tab Bar Controller and a specific tab inside, I would like to use id or css selector:

$scope.tabBarControllers("#tabs-nab-main").tabs("#tab-home").select()

(Not 100% sure how the current ‘directive < - > controller’ relationship linked, does it link to < tabs > in this case ?)

Along the line, $scope.controllers returns all the available controllers in the scope also make sense to me

Here (I think) is the structure of the ionic seed project:

html
  body
    nav-router  # ionic builtin NavController
      nav-page  # customed controllerPage
        tabs    # ionic builtin TabBarController
          tab1  # customed controllerTab1
          tab2  # customed controllerTab2
          ...

My understanding:
1.Controllers get executed top-down.
2.Child scope inherits parent scope’s properties, while parent scope is unware of any new property added to child scope.
3.Which means: when controllerPage is called, the tab bar doesn’t exist yet, because TabBarController hasn’t be called yet.
4.In controllerTabXs, we can retrieve TabBarController using $scope.tabsController, but we can’t use it to set initial selected tab(because the initialization isn’t done?), we can only use it in a later triggered event handler.

E.g. Edit ionic seed-project’s controller.js like this:

angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope) {     // controllerPage
  var tabsController = $scope.tabsController; // undefined
})
.controller('PetsTabCtrl', function($scope, Pets) { // controllerTab1
  var tabsController = $scope.tabsController;       // ok
  tabsController.select(1);                         // won't work

  $scope.$on('tab.shown', function() {
    tabsController.select(1);                       // can work
  });
  ...
})

So:
1.We need a way to set initial selected tab, maybe <tabs tabs-default="1" ...>?
2.We need a way to retrieve tabsController. I think @3dd13’s idea is really great, but maybe we can make it an angular service? E.g.:

<!-- set a name for this tab bar -->
<tabs tabs-name="this-tab-bar-name" ...>
  <tab>...</tab>
  <tab>...</tab>
  ...
</tabs>

app.controller('someCtrl', function(..., TabBarManager) {
  TabBarManager.find('this-tab-bar-name').select(1); // this won't work
  $scope.$on('some event', function() {
    TabBarManager.find('this-tab-bar-name').select(1); // this will work
  });
});

Please let me know if I am getting something wrong, thanks~

1 Like

Thanks @cxyokk, that helps! I have been against using Services in cases like this, mainly because I feel you lose some of the niceties of the scope system and instead have to hack your own (like the find function). We kind of took the iOS method of adding attributes to things when there is a parent view controller. Like a child view controller can access the parent view controllers pretty easily.

Let me think on this. We are going to overhaul the nav system a bit so this should fit into that.

It would be nice to use route parameters to choose the selected tab as well.

For example, in the angular config with a route called friends that has a tab bar with “types” of friends, the type parameter would be used to select the correct tab.

        $routeProvider.when('/friends/:type', {
            templateUrl: 'templates/friends.html',
            controller: 'FriendsController',
            resolve : {
                loadData: function(AccountService) {
                    return AccountService.initialize();
                }
            }
        });

At the very least, if this is not part of core Ionic, we need to be able to manage the selected tab in the controller for the route.

4 Likes

Guys been following this thread let me know when there is a clean solution out there from the community or ionic. I also need to change the icons on the tabs dynamically based the tab status even if that tabs is not currently selected. Thx!

My tab status will be dependent on the server and will change in real time using web sockets.

You can change to any tab by using the $state.go('name-of-state') method. Just inject $state into your controller.

As for changing your icons, set the icon class using an ng-class directive, and you can switch classes (and thus icons) by setting a scope variable.

@jough thank you for this, I’ll give it a whirl.

@rpthis2 we will have better documentation for how to do these things soon!

1 Like

@andy​tjoslin Great looking forward to it! let us know. thx.