Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am upgrading an existing angular app to all the latest versions of angular (v1.2.13), ui-router (v0.2.8), and ui-bootstrap (v0.10.0).

I have nested views that have multiple named views. One of the named views has tabs inside of it. I used to be able to set ui-views within each tab, but that no longer is working. If I don't use the tabs then the named views render correctly.

I have created a plunkr to show what I'm seeing.

Here is my state configuraiton. _split.html has 3 named views: TOP, MIDDLE, and BOTTOM. TOP and MIDDLE both have named views LEFT and RIGHT. TOP has tabs and does not render the views LEFT or RIGHT. MIDDLE has the same named views and they render correctly.

  $stateProvider
      .state("foo", {
        abstract: true,
          url: "/foo",
          templateUrl: '_split.html',
      })
      .state("foo.view", {
        abstract: true,
        url: '',
        views: {
          'TOP': {
            template: '_tabs.html'
          },
          'MIDDLE': {
             templateUrl: '_tabs2.html'
          },
          'BOTTOM': {
            template: '<h2>Bottom</h2>'
          }
        },
      })
      .state("foo.view.tabs", {
        url: '',
        views: {
          'LEFT': {
            template: '<h3>Left</h3>'
          },
          'RIGHT': {
            template: '<h3>Right</h3>'
          }
        }
      })

Is there any way to render ui-view within tabs?

share|improve this question
    
It works good with v0.2.7 (ui-router). I have this problem only with v0.2.8. Maybe it's a bug? –  ekstro Mar 5 at 9:36
    
Confirmed: Something has changed between v0.2.7 and v0.2.8 to break this. In my case, rolling back to v0.2.7 resolved the issue. –  Brent Mar 6 at 17:06
    
Thanks for the info! –  NuclearGhost Mar 6 at 19:19

2 Answers 2

up vote 5 down vote accepted

Yeah, you can render ui-views within tabs. The trick is to use ui-sref in <tab-heading> to control the state/route change, and have the ui-view below the </tabset>. I'm sure there are other ways, but thats how I got tabs working with ui-router.

Heres a working multiple views demo http://plnkr.co/edit/bfO7ne?p=preview

index.html

<tabset>
  <tab>
    <tab-heading>
      <a ui-sref="left">Left</a>
    </tab-heading>
  </tab>
  <tab>
    <tab-heading>
      <a ui-sref="right">Right</a>
    </tab-heading>
  </tab>
</tabset>
<div class="row">
  <br>
  <div class="col-xs-4">
    <div class="well" ui-view="viewA">
      <!--Here is the A content-->
    </div>
  </div>
  <div class="col-xs-4">
    <div class="well" ui-view="viewB">
      <!--Here is the B content-->
    </div>
  </div>
</div>

app.js (ui-router config)

$stateProvider
.state('left', {
  url: "/",
  views: {
    "viewA": {
      template: "Left Tab, index.viewA"
    },
    "viewB": {
      template: 'Left Tab, index.viewB<br><a ui-sref=".list">Show List</a>' +
                '<div ui-view="viewB.list"></div>'
    },
    "viewC": {
      template: 'Left Tab, index.viewC <div ui-view="viewC.list"></div>'
    }
  }
})
.state('left.list', {
  url: 'list',
  views: {
    "viewB.list": {
      template: '<h2>Nest list viewB</h2><ul>' +
                '<li ng-repeat="thing in tab1things">{{thing}}</li></ul>',
      controller: 'Tab1ViewBCtrl',
      data: {}
    },
    "viewC.list": {
      template: 'Left Tab, list.viewC'
    }
  }
})
share|improve this answer
    
I was able to get a working version using this method so thanks. I previously was able to have both tabs already loaded so that switching between them was basically instant. Is there a way to do that? –  NuclearGhost Feb 20 at 15:47
    
Yeah, have a look @ how github.com/ngbp/ngbp build system works, .html templates are injected into the DOM on app load, compiled by grunt. From the README.md: delta:tpls - When any *.tpl.html file within src/ changes, all templates are put into strings in a JavaScript file (technically two, one for src/common/ and another for src/app/) that will add the template to AngularJS's $templateCache so template files are part of the initial JavaScript payload and do not require any future XHR. The template cache files are build/template-app.js and build/template-common.js. –  cheekybastard Feb 21 at 5:31
    
@cheekybastard Is it that you have to click on the link inside the tab header ? In my case, clicking on the square tab header changes the current tab but does not click on the link and therefore does not change the state. –  Stephane Eybert Sep 18 at 17:53
    
Yes its a link driving the state change. The link contains a ui-router directive ui-sref with the ui-router state to call. You can use ng-click to call state change by clicking anywhere on tab header. –  cheekybastard Sep 20 at 4:30

Setting the tab-heading enables the links, but if you click in the tab but outside the link, the link will not activiate. Here is the response I got from ui-router. Thanks to Chris T.

ui-router

plunkr

    <tabset>
    <tab ui-sref="user.list">
        <tab-heading><a ui-sref-active="active">Users</a></tab-heading>
    </tab> 
    </tabset>
share|improve this answer
    
This should be turned into a self-answered question on StackOverflow. It is a crucial example for ui-router beginners/intermediate users on how to set states.js to have tabs visually separated from the tabs contents. IMHO one of the best plunkers about ui-router in conjunction with ui-bootstrap. –  Bonatoc Sep 2 at 13:21
    
Just seeing it now, right after I commented above. Rule I forgot: Always read the entire page on SO before commenting. –  Stephane Eybert Sep 18 at 17:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.