我有深嵌套的路由,比如
/customers
/customers/:customerId
/customers/:customerId/orders
/customers/:customerId/orders/:orderId
和,我有多个命名视图:一个标题,一个侧边栏和主要内容。
// customers.html
<div ui-view="header">
<div ui-view="sidebar">
<div ui-view="content">
我正试图得到一些要求一起工作:
-
customer
应该在/customers/:customerId
下嵌套的所有路由中定义(即应该用定义customer
的控制器创建作用域) - 应该有一组默认的视图,用于嵌套在
/customers/:customerId
和下的所有路由,所有三个视图都应该可以访问父定义的customer
。
我可以实现的第一个要求:
$stateProvider
.state("customers", {
abstract: true,
url: "/customers/:customerId",
templateUrl: "customers.html",
controller: "CustomersController as vm"
})
.state("customers.details", {
url: "",
views: {header: ..., sidebar: ..., content: ...}
})
.state("customers.orders", {
url: "/orders",
views: {header: ..., sidebar: ..., content: ...} // these have to be defined again
})
注意customers.orders
需要重新定义所有三个视图。这并不可怕,但我在想是否有更好的方法。我能想到的唯一方法是拥有另一个级别的状态,但这似乎更糟糕,因为状态名称包含一些与状态无关的东西,只是一个技术工件("默认"):
$stateProvider
.state("customers", {
// as above
})
.state("customers.default", {
abstract: true,
views: {header: ..., sidebar: ..., content: ...}
})
.state("customers.default.details", {
url: "",
views: {content: ...} // don't have to define all three views!
})
请注意,在我的应用程序中,我不能翻转顺序并拥有app
, app.customers
和app.customers.details
之类的东西,其中app
提供三个默认视图,app.customers
提供控制器。真正的应用程序有默认值,我想在路由的不同深度启动。
这是一个可能的解决方案。假设在根html文件中,有一个未命名的ui-view。假设这是您的customer.html文件:
<div ui-view="header">
<div ui-view="sidebar">
<div ui-view>
<div ui-view="content">
你的状态配置可以这样:
$stateProvider
.state("customers", {
abstract: true,
url: "/customers/:customerId",
views: {
'': { // Populate root ui-view with customers.html
templateUrl: "customers.html",
controller: "CustomersController as vm"
},
'header@customers': { // Populate header ui-view in customers.html
...
},
'content@customers': {
...
},
'sidebar@customers': {
...
}
}
})
.state("customers.details", {
url: "",
views: {
'@customers': { // Populate unnamed ui-view in customers.html
...
}
}
})
.state("customers.orders", {
url: "/orders",
views: {
'@customers': {
...
}
}
})
这允许您让标题、侧边栏和内容ui视图对于客户状态的子元素保持不变。如果需要,子视图可以单独覆盖每个视图。因为所有这些视图都是嵌套的,所以它们可以像vm一样访问CustomersController。