Angular UI Router - просмотр в унаследованном состоянии
изменить: На основе ответа от @actor2019 я хочу обновить свой вопрос, чтобы лучше объяснить проблему:
Используя Angular UI-Router (v0.0.2), я настроил приложение, чтобы правильно перемещаться между основными "страницами", /state, наследуя базовое состояние.
Index.html:
<div ui-view></div>
base.html:
<!-- Header -->
<div>
<!-- Header markup -->
<!-- Search View -->
<div ui-view="search"></div>
</div>
<!-- Page Content view -->
<div ui-view></div>
Проблема находится здесь, в файле app.js. Когда я добавляю параметр views
в состояние base
, все перестает работать (100% пустая страница). Без этого параметра страница отображается правильно, но у меня нет вида поиска.
app.js:
$urlRouterProvider.otherwise('/');
//
// Now set up the states
$stateProvider
.state('base', {
abstract: true,
templateUrl: 'views/base.html',
views: {
"search": {
templateUrl: "views/search.html"
}
}
})
.state('base.home', {
url: "/",
templateUrl: "views/home.html"
})
.state('base.page2', {
url: "/page2",
templateUrl: "views/page2.html"
});
Как добавить представления в это базовое состояние родителя?
![enter image description here]()
UPDATE:
Проблема с @actor2019 answer здесь заключается в том, что представление search
становится повторно инициализированным при изменении состояния. Я бы хотел, чтобы представления с базового уровня сохранялись через изменения состояния.
Ответы
Ответ 1
Первая очевидная ошибка:
Вы не можете указать контроллер и шаблон в состоянии во время использования представлений. Они являются взаимоисключающими...
Это связано с тем, что, когда в состоянии нет "представлений", кроме контроллера и шаблона, UI-Router автоматически создает свойство "views" и переносит эти свойства в "пустой" вид...
.state('base', {
abstract: true,
templateUrl: 'views/base.html', //Can't do this
views: { // when this is there.
"search": {
templateUrl: "views/search.html"
}
}
})
Вместо этого выполните:
.state('base', {
abstract: true,
views: {
"": {
templateUrl: 'views/base.html'
},
"search": {
templateUrl: "views/search.html"
}
}
})
Вторая проблема:
Как работает таргетинг на просмотр с вложенными представлениями и т.д., это не очень логично, это может сработать, если вы ограничите свое "я" одним видом в одном представлении до конца, но те, с которых вы начинаете работать с несколькими именованными представлениями, все это запутывает... Добавить неназванные представления сверху, и многие люди теряются...
Способ отображения в UI-маршрутизаторе - худшая часть UI-маршрутизатора...
Учитывая пример, я даже не совсем уверен в том, как настроить таргетинг на представление поиска из вашего абстрактного родительского состояния... Может быть:
.state('base', {
abstract: true,
views: {
"": {
templateUrl: 'views/base.html'
},
"[email protected]": {
templateUrl: "views/search.html"
}
}
})
Если его даже можно заставить работать... В качестве альтернативы вы можете переместить поиск из base.html, но я думаю, вы добавили его туда по какой-то причине.
Вся концепция представления является самой большой причиной, по которой я в конечном итоге написал https://github.com/dotJEM/angular-routing.
Ответ 2
Состояние ребенка должно быть home.search
вместо header.search
. В вашем случае вы можете написать некоторое состояние abstract
, чтобы сохранить макет,
base.html
<div class="row-fluid">
<div class="header">
<div class="span3" ui-view="logo"></div>
<div class="span9" ui-view="menu"></div>
</div>
</div>
<div class="row-fluid">
<div class="content">
<div class="span2" ui-view="sidebar"></div>
<div class="span10" ui-view="entry"></div>
</div>
</div>
в app.js
$stateProvider
.state('base',{
abstract:true,
url:'/',
templateUrl: viewBase+'base.html'
})
.state('base.main',{
url:'',
views:{
"logo":{
templateUrl:viewBase+'main/logo.html'
},
"menu":{
templateUrl:viewBase+'main/menu.html'
},
"sidebar":{
templateUrl:viewBase+'main/sidebar.html'
},
"entry":{
templateUrl: viewBase+'main/entry.html'
}
}})
Ответ 3
Согласно документации ui-router , когда приложение находится в определенном состоянии - когда состояние является "активным" - все его государства-предки также неявно активны. Так, например, когда состояние "contacts.list" активно, состояние "контакты" также неявно активно, потому что это родительское состояние "contacts.list". Статусы детей загружают свои шаблоны в их родительский ui-view. Я бы рекомендовал просмотреть раздел документации под названием Вложенные государства и представления, чтобы получить более полное представление о том, как сделайте это.
В коде, который вы нам предоставили, родительское состояние шаблона поиска home
, а
.state('header.search', {
templateUrl: "views/search.html",
controller: "SearchCtrl"
})
означает, что родительское состояние шаблона поиска должно быть header
, чтобы представление правильно загрузилось. Поэтому я считаю, что следующие изменения в вашем приложении app.js помогут вам решить проблему.
app.js
$stateProvider
.state('home', {
url: "/",
views: {
'': {
templateUrl: "views/mainContent.html",
controller: "MainCtrl"
},
'header': {
templateUrl: "views/header.html"
},
'footer': {
templateUrl: "views/footer.html"
},
}
})
.state('home.search', {
views: {
'search': {
templateUrl: "views/search.html",
controller: "SearchCtrl"
}
})
.state('anotherPage', {
url: "/anotherPage",
templateUrl: "views/anotherPage.html"
});
Ответ 4
Это работает для меня.
$stateProvider
.state('base', {
abstract: true,
url:'/',
templateUrl: 'views/base.html'
})
.state('base.home', {
url: "",
views: {
"[email protected]": {
templateUrl: "views/searchOfHome.html"
}
//[email protected], contentOfHome.html
}
})
.state('base.page2', {
url: "page2",
views: {
"[email protected]": {
templateUrl: "views/searchOfPage2.html"
}
//[email protected], contentOfPage2.html
});
Если 'base'
является корневым состоянием, вам не нужно '@base'