How to reuse the same detail page accross different tabs

In order to explain a bit better what we’re trying to achieve, please refer to the 2 charts below.

I trust that chart 1 needs no explanation as it is the classic use of tabs UI component.

However, in chart 2, we can see that if each tab needs to reuse the same master-detail controllers and templates, it is impossible to achieve out the box, the biggest difficulty being the static / declarative nature of the ui-router states.

Concretely, I’m able to set things up correctly until the master view. I can actually reuse the same list (master) across the 3 tabs, and when I click on a row, the detail page appears, which is good. Unfortunately, it switches to the first tab !!

So the problem is, how can I reuse my templates and controllers code all the way to the detail page, while staying on the currently selected tab?

In other words : I want a details page that would show up in its corresponding tab when you click any item, in any of the lists, of any the tabs.

the following code shows that the ui-router forces you to point to** a “hard-coded” view name, in this case “profile-into”**:

.state('profile.intro', {
        url: '/intro/:username',
        views: {
            **'profile-intro'**: {
                templateUrl: 'app/profile/views/profile-intro.html',
                controller: 'ProfileIntroCtrl'
            }
        }
    })

I need the view name to be dynamically set.

I figure some sort of global controller coupled with a directive could do the trick, but I can’t get my head around it…

Any help is greatly appreciated !!

Here are some posts which basically describe the same need as mine. Unfortunately, these have been left with no concrete solution.

1 Like

Can’t you just use same template and same controller but different State definitions?

for example.

App.Tab1.Details
App.Tab2.Details

where both of them use same template and same controller?

App, Tab1 and Tab2 are all abstract states

  .state "App",
      url: "/app"
      abstract: true
      controller: "appController"
      templateUrl: "templates/app-main-template.html"

.state "App.Tabs",
  abstract: true
  url: "/tabs"
  cache: false
  views:
    "main-view":
      templateUrl: "templates/tabs.html"
      controller: "tabsController"

.state "App.Tabs.Home",
  abstract: true
  url: "/home"
  views:
    "home-tab-view":
      templateUrl: "templates/home-tab.html",
      controller: "homeTabController"

.state "App.Tabs.Home.List",
  url: "/list"
  views:
    "home-list":
      templateUrl: "templates/home-list.html"
      controller: "homeListController"

state "App.Tabs.Home.Details",
  url: "/details"
  views:
    "home-tab-view@App.Tabs":
    templateUrl: "templates/details.html"
    controller: "detailsController"

And then just repeat last 3 states for other tabs

Hi yurinondual !

Thanks for your reply. I thought of that, but what happens if you have 9 tabs or whatever the max limit is?

And in top of that, imagine that for each state, you do have to resolve some data. So, with this solution, this code is then again copied over and over. I’m trying to be keep D.R.Y. …

Taking the App.Tabs.Home.List for example:

.state "App.Tabs.Home.List",
  url: "/list"
  views:
    "home-list": {
        templateUrl: "templates/home-list.html",
        controller: "homeListController",
    },
    resolve: {
        videos : function(VideoCatalog, VideoCatalogMetadata) {
            VideoCatalogMetadata.init();
            return VideoCatalog.getAll();
        }
     }  

But you might be right, this could be the only viable and quick solution…however, with time, it will become a maintenance nightmare…

yes I totally agree, I do the same and I hate all the repetition I have to do in each state resolve. But I couldn’t find any other way so far.

I had a similar issue where I needed to reuse templates across tabs and maintain keeping the user in the active tab. I ended using $ionicTabsDelegate and in my controllers, grabbed the tab index by doing something like this
$scope.selectedTabIndex = $ionicTabsDelegate.selectedIndex();

My issue was having the correct routes. I created routes for each tab that referenced the same template but had a different URL. In my templates, I then loaded in the selectedTabIndex, and when I needed to link to another view, I passed the tab index in my function to change states.

For example, in the template I am re-using, I have this:

ng-click="viewUser(id, selectedTabIndex);"

and in my controller, I have something like this:

$scope.viewUser = function(uid, tabIndex){ if(tabIndex == 2){ $state.go('tab.me-user',{ uid: uid}); } else { $state.go('tab.user-profile',{ uid: uid}); } };

I would rather have multiple routes than multiple templates, so this worked well for me. I’d be very interested to see if someone else comes up with another way to achieve this.

1 Like

Hi!
Does anyone get the solution the for this issue. Please can anyone help me to resolve this issue.