Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UI Router: redirect to child state when navigating to abstract parent state

In my music app, I have an ng-repeat on the top-level states of my app to create navigation links. One of the top-level states, called library, is abstract and has child states (which are navigable using tabs). Since I am using an ng-repeat, the abstract state has a directive of ui-sref="library". However, it's not possible to navigate to an abstract parent state like that, instead I would need to write ui-sref="library.albums". I am unable to do this because of the ng-repeat data coming directly from the state provider. How can I set a default child state on "library" so that whenever that state is visited, it redirects to the child?

Here's a diagram of my setup: enter image description here

like image 376
Alex Wohlbruck Avatar asked Aug 05 '16 22:08

Alex Wohlbruck


2 Answers

Found this question when I was looking for the same and then I found this on Angular UI-Router's FAQ page. https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions

How to: Set up a default/index child state

  1. Make the parent state abstract.

    $stateProvider
        .state('library', {
            url: '/library',
            abstract: true,
            template: '<ui-view></ui-view>'
        })
        .state('library.albums', {
            url: '/albums',
            template: '<h1>Albums</h1>'
        });
    
  2. Then if you give the child state an empty URL, it will match the exact parent's URL. However, if you want to keep a separate URL for the child, you can do this:

    $urlRouterProvider.when('/library', '/library/albums');
    

Read the given GitHub WIKI URL if you need more information.

like image 190
ssudaraka Avatar answered Nov 04 '22 13:11

ssudaraka


Unfortunately you can't use ui-sref to link to an abstract state.

you could try something like:

$rootScope.$on('$stateChangeStart', function(event, toState, toParams){
    if(toState.name == 'library'){
        event.preventDefault();
        $state.go('library.albums', toParams);
    }
}

Rather than hardcoding each state redirection though, you could do something like:

$stateProvider
    .state('library', {
        url: '/library',
        data: {
            redirect: 'library.albums'
        }
    })
    .state('library.albums', {
        url: '/albums',
        data: {
            redirect: false
        }
    });

$rootScope.$on('$stateChangeStart', function(event, toState, toParams){
    if(toState.data && toState.data.redirect){
        event.preventDefault();
        $state.go(toState.data.redirect, toParams);
    }
}
like image 20
plong0 Avatar answered Nov 04 '22 12:11

plong0