我正在尝试使用ui路由器,使用angular中的嵌套状态创建一个基本布局系统。
我想要的是,任何"子状态"都可以覆盖顶级状态的'layout'
部分,以便根据站点的区域使用不同的站点布局。
给定以下系统/server/views/index.html:
<section data-ui-view="layout" ></section>
以及两种布局将互换为上述布局:system/public/views/layouts/standard.html:
<div class="navbar navbar-inverse navbar-fixed-top" data-ui-view="header" data-role="navigation"></div>
<section class="container-fluid">
<section data-ui-view ></section>
</section>
system/public/views/layouts/full-width.html:
<div class="navbar navbar-inverse navbar-fixed-top" data-ui-view="header" data-role="navigation"></div>
<section class="container">
<section data-ui-view ></section>
</section>
示例内容系统/public/views/index.html
<div>some sample content</div>
最后是路由器:
function($stateProvider, $urlRouterProvider) {
// For unmatched routes:
$urlRouterProvider.otherwise('/');
// states for my app
$stateProvider
.state('root', {
url: '/',
abstract: true,
views: {
'layout@': {
templateUrl: 'system/views/layouts/standard.html'
},
'header@root': {
templateUrl: 'system/views/partials/header.html'
}
}
})
.state('root.home', {
url: '',
views: {
'header@root': {
templateUrl: 'system/views/partials/header2.html'
},
'': {
templateUrl: 'system/views/index.html'
}
}
});
}
以上工作。我可以在子状态中交换标题,但如果我添加"布局"的覆盖:
function($stateProvider, $urlRouterProvider) {
// For unmatched routes:
$urlRouterProvider.otherwise('/');
// states for my app
$stateProvider
.state('root', {
url: '/',
abstract: true,
views: {
'layout@': {
templateUrl: 'system/views/layouts/standard.html'
},
'header@root': {
templateUrl: 'system/views/partials/header.html'
}
}
})
.state('root.home', {
url: '',
views: {
'header@root': {
templateUrl: 'system/views/partials/header2.html'
},
'': {
templateUrl: 'system/views/index.html'
},
--->>> 'layout@': {
templateUrl: 'system/views/layouts/full-width.html'
}
}
});
}
当我添加'layout@'
时,date-ui-view="layout"
确实被正确加载,但标头和未经修改的子ui视图不会被替换。
你知道这里发生了什么吗?
如果这不应该奏效,还有什么替代方法?
重点是覆盖子状态'root.home'
中的模板,如下所示:
.state('root.home', {
...
->> 'layout@': {
templateUrl: 'system/views/layouts/full-width.html'
}
实际上是从父"根"中完全删除任何部分。所以现在我们必须将其用于兄弟视图:
'header@root.home': { // see the 'root.home' after @
templateUrl: 'system/views/partials/header2.html'
},
'@root.home': { // see the 'root.home' after @
templateUrl: 'system/views/index.html'
},
请看,我们在@
之后使用了root.home
。即:我们明确表示:
- 在this当前
'root.home'
状态中查找ui-view="header"
和未命名的ui-view=""
在父状态"home"中没有目标,因为我们完全跳过了它。
在这种情况下,文档中的示例实际上是自我描述的:
视图名称-相对名称与绝对名称
(引用自述片段)
$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's //
////////////////////////////////////
// Relatively targets the 'detail' view in this state's parent state, 'contacts'.
// <div ui-view='detail'/> within contacts.html
"detail" : { },
// Relatively targets the unnamed view in this state's 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" : { }
// Absolutely targets the unnamed view in parent 'contacts' state.
// <div ui-view/> within contacts.html
"@contacts" : { }
// absolutely targets the 'status' view in root unnamed state.
// <div ui-view='status'/> within index.html
"status@" : { }
// absolutely targets the unnamed view in root unnamed state.
// <div ui-view/> within index.html
"@" : { }
});
此外,请注意这个重要事实:
仅按视图层次结构的作用域继承
请记住,如果状态的视图是嵌套的,则作用域属性只能沿状态链向下继承。范围属性的继承与状态的嵌套无关,一切都与视图(模板)的嵌套有关。
完全有可能您有嵌套状态,其模板会在站点中的各种非嵌套位置填充ui视图。在这种情况下,您不能期望在子状态的视图中访问父状态视图的范围变量。
也就是说,我们无论如何都不能从父"根"状态继承,因为继承仅限于视图视图。。。