问题
I have 2 ui-view
directives in my application. One contains subnavigation and the other is the actual page content. My subnavigation is a tree structure, and when you click on an end node (or a leaf) should be the only time the content view gets updated. Whenever you click non-leaf nodes in the subnavigation, I would like the content view to stay the same while the subnavigation view changes.
What is happening is whenever I switch to a state that does not define one of the views, the view gets cleared out. I want it to stay how it was previous to me changing state. Has anyone accomplished this?
Code:
<!--NOTE THAT THESE ARE SIBLING ELEMENTS, NOT NESTED -->
<div id="subNav" ui-view="subNav"></div>
<div id="content" ui-view="content"></div>
Here is my route setup. Note that State1 only should update the subnav
view and State2 should only update the content
view.
$stateProvider
.state('State1', {
url: '/State1',
views: {
"subnav": {
templateUrl: "views/subnav.html",
controller: "SubNavController"
}
}
})
.state('State2', {
url: '/State2',
views: {
"content": {
template: "<p>State 2</p>"
}
}
});
Here is a plnkr of what is is currently doing: http://plnkr.co/edit/TF7x5spB8zFLQPzrgZc9?p=preview
回答1:
I would say, that the way to go here is really very clear:
Multiple Named Views
Nested States & Nested Views
I am using this technique, in very similar scenario: left column is a list, right (large area) is a place for a detail. There is an example
The state def would be:
$stateProvider
.state('index', {
url: '/',
views: {
'@' : {
templateUrl: 'layout.html',
controller: 'IndexCtrl'
},
'top@index' : { templateUrl: 'tpl.top.html',},
'left@index' : { templateUrl: 'tpl.left.html',},
'main@index' : { templateUrl: 'tpl.main.html',},
},
})
.state('index.list', {
url: '/list',
templateUrl: 'list.html',
controller: 'ListCtrl'
})
.state('index.list.detail', {
url: '/:id',
views: {
'detail@index' : {
templateUrl: 'detail.html',
controller: 'DetailCtrl'
},
},
})
So in our case, it could be like this:
- the parent state would have a template for both states (layout) and also will inject the navbar
- the child will just inject the view into main area
the Parent state:
.state('State1', {
url: '/State1',
views: {
"bodyArea" { template: "body.thml"},
"subnav@State1": {
templateUrl: "views/subnav.html",
controller: "SubNavController"
}
}
})
So what we can see, the template for both states, the layout is defined on the State1
as a view placed in "bodyArea".
The other view (original) is injected into that template, via absolute name "subnav@State1". I.e. 2 views defined for one parent state...
The Child state:
.state('State2', {
parent: 'State1', // a child needs parent
url: '/State2',
views: {
"content": {
template: "<p>State 2</p>"
}
}
})
Here, we just say, that State1 is parent of State2. That means, that the "content" target/anchor (ui-view="content"
) must be part of the views defined in State1. The best place here would the "body.html"...
EXTEND: based on comments and this plunker with some issues, I created its updated version. Navigation to Main1 is broken (to be able to compare), but Main2 and Main3 are working.
- Main2 is working because it has the similar def as
index
state - Main3 is on the other hand child of the
index
state
The absolute and relative naming in action should be clear from this snippet:
the index:
$stateProvider
.state('index', {
url: '/',
views: {
'@': {
templateUrl: 'layout.html'
},
'mainNav@index': {
template: '<a ui-sref="Main1">Main1</a><br />'
+ '<a ui-sref="Main2">Main2</a><br />'
+ '<a ui-sref="Main3">Main3</a>'
},
'subNav@index' : {
template: '<p>This is the sub navigation</p>'
},
'content@index': {
template: '<p>This is the content</p>'
}
}
})
the Main1 with issues
.state('Main1', {
url: '/Main1',
views: {
/*'mainNav': {
},*/
'subNav': {
template: '<a ui-sref="Sub1">Sub1</a><a ui-sref="Sub2">Sub2</a>'
},
'content': {
template: '<p>This is the content in Main1</p>'
}
}
})
working states
.state('Main2', {
url: '/Main2',
views: {
'': {
templateUrl: 'layout.html'
},
'mainNav@Main2': {
template: '<a ui-sref="Main1">Main1</a><br />'
+ '<a ui-sref="Main2">Main2</a><br />'
+ '<a ui-sref="Main3">Main3</a>'
},
'subNav@Main2': {
template: '<a ui-sref="Sub1">Sub for Main2</a>'
},
'content@Main2': {
template: '<p>This is the content in Main2</p>'
}
}
})
.state('Main3', {
parent: 'index', // PARENT does the trick
url: '/Main3',
views: {
'subNav': { // PARENT contains the anchor/target - relative name is enough
template: '<a ui-sref="Sub1">Sub for Main3</a>'
},
'content': {
template: '<p>This is the content in Main3</p>'
}
}
})
来源:https://stackoverflow.com/questions/25815505/how-can-i-persist-sibling-ui-views-when-changing-state