Reputation: 5095
I'm using AngularJS and the Angular UI-Router.
ui-view
in the parent state's view with their own view.ui-view
's in their view, each filled with views.Attempt at a diagram:
Parent: <ui-view>
filled by
Child: <ui-view> <ui-view> <ui-view>
filled filled filled
I have a state called category-details
. Inside the view for this abstract state I have an unnamed ui-view
. In one of the two child states (category-details.selected
) I want to use multiple named views.
Here is the abstract state. Very basic, but included for your reference.
.state('category-details', {
abstract: true,
data: {
pageTitle: 'Category Details'
},
templateUrl: "views/category-details.html",
})
In the category-details.selected
state (the state which will have multiple named views), I set the unnamed ui-view
of category-details.html
to category-details-selected.html
:
.state('category-details.selected', {
views: {
'': {
templateUrl: 'views/category-details-selected.html',
controller: 'CategoryDetailsSelectedCtrl'
}
}
})
Inside of the category-details-selected.html
view I have three named ui-views
:
<div ui-view="firstNamedView"></div>
<div ui-view="secondNamedView"></div>
<div ui-view="thirdNamedView"></div>
Finally, I define a state for setting these three ui-view
's to meet the third part of my desired behavior:
.state('category-details.selected.aspect', {
url:"/category-details/:selectedCategory",
views: {
'firstNamedView': {
templateUrl: 'views/first-named-view.html',
controller: 'FirstNamedViewCtrl'
},
'secondNamedView': {
templateUrl: 'views/second-named-view.html',
controller: 'SecondNamedViewCtrl'
},
'thirdNamedView': {
templateUrl: 'views/third-named-view.html',
controller: 'ThirdNamedViewCtrl'
}
}
});
Adding the category-details.selected.aspect
state to set constant elements (the three ui-view
's) of the category-details-selected
view is unnecessary. It forces creating an extra state every time I want multiple named views.
I believe I should be able to move the url and views of the category-details.selected.aspect
state into the views
component of its parent state (category-details.selected
). This would look like:
.state('category-details.selected', {
url:"/category-details/:selectedCategory",
views: {
'': {
templateUrl: 'views/category-details-selected.html',
controller: 'CategoryDetailsSelectedCtrl'
},
'firstNamedView': {
templateUrl: 'views/first-named-view.html',
controller: 'FirstNamedViewCtrl'
},
'secondNamedView': {
templateUrl: 'views/second-named-view.html',
controller: 'SecondNamedViewCtrl'
},
'thirdNamedView': {
templateUrl: 'views/third-named-view.html',
controller: 'ThirdNamedViewCtrl'
}
}
})
This resulted in the unnamed ui-view
being set correctly, but the three named ui-view
's were not filled.
Since selecting the three named ui-view
's was the problem, I then attempted to select them with absolute selectors
described here instead. This did not fix the problem. I tried:
firstNamedView
firstNamedView@
[email protected]
(others of course)
Is what I'm imagining possible, is another way better, or is my current method the best? It boils down to assigning the child ui-view
s of a parent ui-view
being set at the same time. I thought the last sentence was too confusing alone, so I included the entire example.
Please let me know if I can provide any more clarification such as versions. Thank you.
Upvotes: 3
Views: 561
Reputation: 2587
Abstract states need their own
<ui-view/>
for their children to plug into.
Parent state category-details
is abstract
state. Child state will need some reference ui-view to plug that state into. In your I believe the view /category-details.html
does not any ui-view (as you have mentioned that category-details-selected.html
contains the ui-view).
Try this:
.state('category-details', {
abstract: true,
data: {
pageTitle: 'Category Details'
},
templateUrl: "views/category-details-selected.html",
})
.state('category-details.selected', {
url:"/category-details/:selectedCategory",
views: {
'firstNamedView': {
templateUrl: 'views/first-named-view.html',
controller: 'FirstNamedViewCtrl'
},
'secondNamedView': {
templateUrl: 'views/second-named-view.html',
controller: 'SecondNamedViewCtrl'
},
'thirdNamedView': {
templateUrl: 'views/third-named-view.html',
controller: 'ThirdNamedViewCtrl'
}
}
})
Here, we are giving abstract view a template, which has ui-view in it, for child to populate.
Have a look at documentation of ui-router: Abstract State for more information.
EDIT: I had assumed that views/category-details.html
does not contain any ui-view. However, it was then pointed out that, views/views/category-details.html
does have ui-view
This is what works for me:
category-details.html:
<div ui-view=""></div>
category-details-selected.html:
<div ui-view="firstNamedView"></div>
<div ui-view="secondNamedView"></div>
<div ui-view="thirdNamedView"></div>
router:
.state('category-details', {
abstract: true,
data: {
pageTitle: 'Category Details'
},
templateUrl: "../app/atest/category-details.html",
})
.state('category-details.selected', {
url: "/atest",
views: {
'': {
templateUrl: "../app/atest/category-details-selected.html",
// controller: 'approvalsCtrl as vm',
},
'[email protected]': {
templateUrl: '../app/atest/first.html',
// controller: 'approvalsCtrl as vm',
},
'[email protected]': {
templateUrl: '../app/atest/second.html',
// controller: 'approvalsCtrl as vm',
},
'[email protected]': {
templateUrl: '../app/atest/third.html',
// controller: 'approvalsCtrl as vm',
}
}
})
I could see that you have mentioned you tried out using [email protected]
, but it didn't worked for you. The above example is working for me. Check if you category-details.html
and category-details-selected.html
view contain proper ui-view
.
Upvotes: 1