andre_bauer
andre_bauer

Reputation: 850

Angular Nested states not working as expected

Can someone see why this is not working? /series is not loading the Gallery, however the /series/:id/seasons part is working. (Its not a missing ng-view problem see working code below!)

angular.module('xbmcremoteApp')
  .config(function ($stateProvider) {
    $stateProvider
      .state('series', {
        url: '/series',
        templateUrl: 'app/series/series.html',
        controller: 'SeriesCtrl'
      }).state('series.gallery', {
        url: '',
        templateUrl: 'app/series/series-gallery/series-gallery.html',
        controller: 'SeriesGalleryCtrl'
      }).state('series.seasons', {
        url: '/:id/seasons',
        templateUrl: 'app/series/seasons/seasons.html',
        controller: 'SeasonsCtrl'
      });
  });

if i change it to this it works but thats not what i want:

angular.module('xbmcremoteApp')
  .config(function ($stateProvider) {
    $stateProvider
      .state('series', {
        url: '',
        templateUrl: 'app/series/series.html',
        controller: 'SeriesCtrl'
      }).state('series.gallery', {
        url: '/series',
        templateUrl: 'app/series/series-gallery/series-gallery.html',
        controller: 'SeriesGalleryCtrl'
      }).state('series.seasons', {
        url: '/series/:id/seasons',
        templateUrl: 'app/series/seasons/seasons.html',
        controller: 'SeasonsCtrl'
      });
  });

EDIT and soltuion:
My post lacked some information. To make that clear:
I want to display a gallery when the /seriesurl is called. And i want to display the seasons with the seasons url. No more views!
Found an very easy solution. Setting the abstract property to true forces the stateprovider to use the child view.

....
.state('series', {
    abstract:true,  //adding this line makes the states work as expected
    url: '/series',
    templateUrl: 'app/series/series.html',
    controller: 'SeriesCtrl'
  })
....

Upvotes: 0

Views: 567

Answers (1)

Radim Köhler
Radim Köhler

Reputation: 123901

In the first definition the url /series is evaluated as a root state 'series'

.state('series', {
    url: '/series',          // url evaluation will stop here, because
    ...                      // there is a match for /series
  }).state('series.gallery', { // this will never be reached via url
    url: '',                   // but ui-sref="series.gallery" will work
    ...

While the second mapping does distinguish both states, and '/series' will navigate to 'series.gallery' state :

.state('series', {
    url: '',                   // url like "#" will navigate there
    ...
  }).state('series.gallery', { // url /series will trigger this child state
    url: '/series',
    ...

In general, if states should be unique by url, each of them should have some defintion. So mostlikely this should be working as inteded:

.state('series', {
    url: '/',                   // url like "#/" will navigate to series
    ...
  }).state('series.gallery', { // url '/series' will trigger this
    url: '^/series',
    ...

check the magical sign: ^:

If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.

Upvotes: 1

Related Questions