Angularjs - ui.router sibling states
I am using bootstrap
with angularjs
(and ui-router
for routing).
I have navbar
where every tab click should see another nested one in it navbar
. The nested one navbar
is a ui-view (should I do it differently?).
The problem is when I click one li in the main navbar all four nested navbar displays are shown.
div(ng-controller='MyCtrl')
h1 Header
ul.nav.nav-tabs(role="tablist")
li.active(role="presentation")
a(ui-sref='first_nested_state') General
div(ui-view)
li.active.navbar-padding-left(role="presentation")
a(ui-sref='second_nested_state') User
div(ui-view)
li.active.navbar-padding-left(role="presentation")
a(ui-sref='third_nested_state') User
div(ui-view)
li.active.navbar-padding-left(role="presentation")
a(ui-sref='fourth_nested_state') User
div(ui-view)
And here is one nested navbar (they all look the same except for the names):
div(ui-view)
ul.nav.nav-tabs(role="tablist", color="red")
li.active(role="presentation")
a(ng-href='#') A
li.active(role="presentation")
a(ng-href='#') B
li.active(role="presentation")
a(ng-href='#') C
And my state config:
$stateProvider
.state('main_nav_bar', {
url: '/main_nav_bar',
templateUrl: 'main_nav_bar.html'
})
.state('first_nested_navbar', {
parent: 'main_nav_bar',
url: '/first_nested_navbar',
templateUrl: 'first_nested_navbar.html'
})
.state('second_nested_navbar', {
parent: 'mainNavBar',
url: '/second_nested_navbar',
templateUrl: 'second_nested_navbar.html'
})
I am using coffeescript
and jade
.
source to share
The problem here ("... when I click one <li>
... all four nested views in the navigator are shown ...") is due to redefining div(ui-view)
This means that the DOM page contains 4 <div ui-view></div>
. They are all used as the target for the selected content. This is why we see it four times.
The solution should be in named views:
In our case, we have to use this HTML definition
li.active(role="presentation")
a(ui-sref='first_nested_state') General
div(ui-view="first") // give it name "first"
li.active.navbar-padding-left(role="presentation")
a(ui-sref='second_nested_state') User
div(ui-view="second") // give it name "second"
...
And use explicit representations of our state definitions:
...
.state('first_nested_navbar', {
parent: 'main_nav_bar',
url: '/first_nested_navbar',
views : {
'first' : { // now we explicitly inject into anchor/target "first"
templateUrl: 'first_nested_navbar.html'
},
}
})
.state('second_nested_navbar', {
parent: 'mainNavBar',
url: '/second_nested_navbar',
views : {
'second' : { // here we target the ui-view="second"
templateUrl: 'second_nested_navbar.html'
},
}
})
Check out a really well documented example here , see below snippet from that source:
$stateProvider
.state('contacts', {
// This will get automatically plugged into the unnamed ui-view
// of the parent state template. Since this is a top level state,
// its parent state template is index.html.
templateUrl: 'contacts.html'
})
.state('contacts.detail', {
views: {
////////////////////////////////////
// Relative Targeting //
// Targets parent state ui-view //
////////////////////////////////////
// Relatively targets the 'detail' view in this state parent state, 'contacts'.
// <div ui-view='detail'/> within contacts.html
"detail" : { },
// Relatively targets the unnamed view in this state parent state, 'contacts'.
// <div ui-view/> within contacts.html
"" : { },
///////////////////////////////////////////////////////
// Absolute Targeting using '@' //
// Targets any view within this state or an ancestor //
///////////////////////////////////////////////////////
// Absolutely targets the 'info' view in this state, 'contacts.detail'.
// <div ui-view='info'/> within contacts.detail.html
"info@contacts.detail" : { }
// Absolutely targets the 'detail' view in the 'contacts' state.
// <div ui-view='detail'/> within contacts.html
"detail@contacts" : { }
source to share