У меня есть глубоко вложенные маршруты, например
/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 файле у вас есть неназванный u-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-views остаются постоянными для детей состояния клиентов. При необходимости дети могут переопределять каждое представление индивидуально. Поскольку все эти представления вложены, они будут иметь доступ к CustomerController как vm.