Do you know a way in ui-router to get the list of child states of a given state?
I'm implementing a complex SPA with maybe 4 level deep navigation using ui-router.
I would like to implement a navigation tab interface for the second level generated automatically from the router table.
For that, I need to get the list of direct children of a given state (maybe is an abstract state). The only way that I've found to get the states is to do a $state.get()
and obtain the full list of states, but that means that I'll have to parse child states on my own, and I think that's code already written in ui-router.
I let this question here in case there's anyone with experience in the source code or know of a plugin or module that can help me on this. Meanwhile I will do a research on my own and post results if I find something.
I did this which is easier and faster:
var chillin = $state.get().filter(function(cState) { return cState.name.indexOf('parent.state.') === 0 });
In the end, had to implement the functionality myself.
In the controller of the abstract route that has the tab interface, filtered the states using a regular expression taking advantage of the default naming convention for routes:
var routeName='Root.Parent'; // this is the "actual" route
// this regex is going to filter only direct childs of this route.
var secondRouteOnlyRegex = new RegExp(routeName + "\.[a-z]+$", "i");
var states = $state.get();
// this uses lodash to filter the states based on the regex
var navLinks = _.filter(states, (s) => {
return secondRouteOnlyRegex.test(s.name) && !s.abstract;
});
$scope.tabs = navlinks;
My route definitions have a data
property that contains the title and other metadata needed to render the tabs.
My template looks something like this (using bootstrap):
<ul class="nav nav-tabs">
<li ng-repeat="state in tabs" ui-sref-active="active">
<a href="{{state.url}}" ui-sref="{{state.name}}">{{state.data.title}}</a>
</li>
</ul>
If you use stateHelper, it enables you to register states like this (from the stateHelper readme):
angular.module('myApp', [ 'ui.router', 'ui.router.stateHelper' ])
.config(function(stateHelperProvider){
stateHelperProvider
.state({
name: 'root',
templateUrl: 'root.html',
children: [
{
name: 'contacts',
template: '<ui-view />',
children: [
{
name: 'list',
templateUrl: 'contacts.list.html'
}
]
},
{
name: 'products',
templateUrl: 'products.html',
children: [
{
name: 'list',
templateUrl: 'products.list.html'
}
]
}
]
})
.state({
name: 'rootSibling',
templateUrl: 'rootSibling.html'
});
});
In your navigation controller you can then use the children
attribute on the "root" state. For instance, I'm using this to display all children of the current state:
angular.module('app')
.controller('TransportController', function($scope, $state) {
$scope.items = $state.current.children;
});
Hope this helps.