Nested States & Views in Ionic?

I’ve been wrestling with Ionic for the past two days to achieve nested views. I’ve simply attempted the following:

    .state('main', {
  url: '/main',
  views: {
    'search': {
      templateUrl: 'templates/searchBar.html',
      controller: 'SearchController'
    },
    'scores': {
      templateUrl: 'templates/scoreBar.html',
      controller: 'ScoreController'
    },
    'userCards': {
      templateUrl: 'templates/cards.html',
      controller: 'CardsController'
    }
  }
})

It seems to show up in the DOM, but doesn’t appear, because it’s nested inside Ionic’s nav-view directive.

What’s the general pattern to follow when I need to break away from some of Ionic’s defaults or can I achieve a state with three nested views easily in Ionic. Sorry if this sound elementary, but it works when done in vanilla Angular. Any help is greatly appreciated. Thanks.

Would you be able to create a plunkr? You could start by forking this one: http://plnkr.co/edit/O6yv2iCraUUSQR5vlTsg?p=preview

I’ve done that too. I found it to be like it is documented on the ui-router wiki at github.

basically it should look like this, according to your states config:

<nav-view>
    <nav-view name="search"></nav-view>
    <nav-view name="scores"></nav-view>
    <nav-view name="userCards"></nav-view>
</nav-view>

Make sure you name your nav-views (or ui-views). nav-view is provided by Ionic and I think they work like the ui-view from ui-router. At least, they did for me. It’s important to only have one unnamed nav-view.

1 Like

adam: Thanks for the reply.
daniel: Also thanks for the reply.

I just got some in-person help from Ari Lerner of (https://www.ng-book.com/) and figured out what the issue was. It’s not noted in your documentation, but we discovered a solution:

// MAIN
.state('main', {
  url: '/main',
  abstract: true,
  templateUrl: 'templates/main.html'
})
.state('main.stream', {
  url: '/stream',
  views: {
    'search@': {
      templateUrl: 'templates/search.html',
      controller: 'SearchController'
    },
    'scores@': {
      templateUrl: 'templates/scores.html'
      // controller: 'ScoresController'
    },
    'userCards@': {
      templateUrl: 'templates/cards.html',
      controller: 'CardsController'
    }
  }
})

The important thing to note is the @ suffix appended to each named view. I had a main.html template which I wanted the nested views under. This was the only thing I hadn’t tried from the documentation and, sure enough, it ended up being the thing that solved my issue. For my search view, the code is essentially saying: **load search.html template into the element with ui-view="search" AT the main state **.

Hope this will be useful for somebody. Many thanks to the both of you for your help!

3 Likes

Well, thank you Sudo! Just lost few hours braking my had between ui-router wiki and ionic docs, and I thought I made all by the book :smiley: damn @ :smile:
thanks again!!

I hope this kind of things will eventually pop in the docs

Would it be at all possible for you to post an example plunker showing this in action? I’m interested to see full source (i.e how your js code and HTML looks)

I’m trying to make two views that sit in the same view, effectively: “halving the view into two views”.

Edit: this in ionic… http://plnkr.co/edit/gmtcE2?p=preview is what I’m trying to do. I’m gonna play with this plunker, and see what I can do…

I haven’t had any luck with displaying “stacked” ion-content or ion-view. They always overlap, each using the entire display area. I’ve been using standard html elements, along with ui.router’s nested states to simultaneously display multiple views in one screen. But daniel’s example seems to work using multiple ion-nav-views

Yeah that’s what I’m finding.

I’ve managed to partly convert the plunker into ionic…

It still sorta works but the nav bars won’t work and (as you say) I haven’t managed to get multiple views in one screen.

What I really need is a plunker that does exactly this: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views but the people who wrote the docs seems to have neglected to write a plunker for that piece of functionality. My next step would be then to try and translate this to ionic

Ok I figured out my issue, my child state only defined views: {…} and didn’t have a templateUrl or controller property on the main child state definition.

demo: http://codepen.io/ItsLeeOwen/pen/faCql

Yes, I’ve tried playing with that, ion views don’t seem to be totally the same as ui-views and ion-nav-view seems to take over the full screen.

I’m going to leave this plunker with as far as I got: http://plnkr.co/edit/UkXhXK?p=preview

I’m then going to fork it and try adding my ionic style views, basically I need a second (ionic) view on the same page below the first as I need the second view to be vertically scrollable, i.e…

---------------
| ________ |
| |               | |
| |Top view | |
| |------------| |
|                  |
| ________ |
| |               | |
| |scrollable| |
| |------------| |
|_________|

Edit: ok this is interesting…

I “can” get ion-views to play nicely… sort of. I put named ion-nav-views inside an anonymous ion-view, I now have stacked ion lists!.. except the second page that you click through doesn’t work and the bottom list isn’t independantly scrollable… but nevertheless it looks like this “may” be possible.

Hey There,

I seem to be having the exact same problem descibed in by @andmar8 above. I have some nested ‘ion-nav-view’ and within the deep-nested views the lists don’t scroll.

Is there a solution to make the lists above ( Contacts & Things) scrollable ?

Hi gibiman,
I have to admit I haven’t been that involved ionic for many, many months so haven’t looked what may have become possible since May, however…

  • I notice ionic beta 14 is going to angular 1.3 which may change things
  • I “have” been playing a lot with “just” plain 'ol angular (no ionic) and have become more accustomed to its nuances and how it works, I can heartily recommend you doing the same, you really get a much greater understanding of ionic by actually understanding the underlying framework (angular). Also, heavily research the differences between standard angular routing and the ui-router plugin (which is what gives ionic its nested views). Briefly, what I can say now is…
  • I can see why so many angular purists prefer default routing to the nested routing of ui-router, it is almost worth avoiding nested views and adjusting your application to use the out of the box angular routing, it makes things a million times easier, BUUUTTTTT, you can’t (as) easily get side bars with their own scopes, which is a very nice part of ui-router.
  • As I say, I haven’t played with this problem in some months, but I suspect the answer may well be “use custom directives”, seriously, research directives, how to make them and how they work, wow are they cool. I completely understand why angular fans go crazy for them, and indeed, why ionic is so good (it has tons of directives). My suspicions is you may be able to create two, css positioned/sized directives that are independant, have their own scopes and would play nicely on the same view together, but I’m yet to test this hunch.

I think that’s an important feature they should include. A lot of app re-use the same controllers and views and of course it would be nice to not have to modify only one file.
I have struggled a lot before finding out the “viewName@abstractView” tricks to have several views with a common controller and template but I still have error with the navigation bar and the history in general…Unerstanding the whole $ionicHistory would take a lot of time to customize our apps.

How does the code changes if one of top ion-nav-view is named ??

I have an application using the Tabs template as so:

 // setup an abstract state for the tabs directive
   .state('tab', {
    url: '/tab',
     abstract: true,
     templateUrl: 'templates/tabs.html',
  })

   // Each tab has its own nav history stack:
   .state('tab.trips', {
     url: '/trips',
     views: {
       'tab-trips': {
          templateUrl: 'templates/trips.html',
          controller: 'TripsCtrl',
        }
      }
    })

.state('tab.trip-detail', {
    url: '/trips/:tripId',
    views: {
      'tab-trips': {
        templateUrl: 'templates/trip-detail.html',
        controller: 'DestinationCtrl',
      }
    }
  })

Here we have the abstract state ‘tab’, then the first master view in ‘tab.trips’ and its detail view ‘tab.trip-detail’.

Inside ‘tab.trip-detail’ I want to be able to display different templates for different states in this view.

Not sure how to set up the states for this.