Многоуровневое UI-маршрутизатор AngularJS
Как Angular есть SPA, который потрясающий, но что, если мне нужна какая-то другая страница, не связанная с index.html, как реализованы состояния UI-Router с разными ui-view?
Например, у меня есть index.html:
<!DOCTYPE html>
<html data-ng-app="npAdmin">
<head>
...
</head>
<body>
<header>
<data-user-profile class="user-profile"></data-user-profile>
</header>
<section class="content-wrapper">
<aside data-main-menu></aside>
<div class="main-content" data-ui-view></div>
</section>
<footer class="row"></footer>
...
</body>
</html>
app.js
var app = angular.module('npAdmin', ['ui.router']);
app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', function($httpProvider, $stateProvider, $urlRouterProvider) {
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: '/app/dashboard/dashboard.html',
controller: 'DashboardCtrl'
})
.state('crm', {
url: '/crm',
templateUrl: '/app/crm/crm.html',
controller: 'CrmCtrl'
})
...
Теперь мне нужно login.html, который полностью отличается от index.html(не нужен заголовок индекса, нижний колонтитул, боковая панель), но config stateProvider только смотрит на index.html ui-view и изменения содержание к нему со стороны государств. Как совместить login.html?
Кажется, это не так сложно, но я не понимаю.
Ответы
Ответ 1
Как и ожидалось, это не так сложно, есть plunker.
Хитрость заключается в перемещении общего материала для всех видов внутри конкретного шаблона, например. common.html
и создать абстрактное состояние. Другими словами, index.html
останется чистым:
<body>
<div ui-view=""></div>
</body>
И его предыдущий контент (содержимое index.html
) будет перенесен на common.html
. Определение состояния может выглядеть так:
$stateProvider
.state('common', {
templateUrl: 'tpl.common.html',
abstract: true,
})
.state('dashboard', {
url: '/dashboard',
parent: 'common',
...
})
.state('crm', {
url: '/crm',
parent: 'common',
...
})
.state('login', {
url: '/login',
templateUrl: 'tpl.login.html',
});
$urlRouterProvider.otherwise('/crm');
Что такое интересный (я бы сказал), мы представили состояние абстрактное, без URL. Таким образом, вся текущая логика останется, только абстрактный будет играть роль шаблона макета .
Подробнее здесь: пример
Ответ 2
У меня также была эта проблема раньше, если вы заинтересованы, обратитесь к ЭТО. В этой связи я также обрабатывал returnUrl
и 401 http status code
, если пользователь не авторизовался.
В вашем случае я предлагаю вам создать ваше приложение следующим образом:
index.html
<!DOCTYPE html>
<html data-ng-app="npAdmin">
<head>
...
</head>
<body data-ui-view>
</body>
...
</html>
main.html:
<header>
<data-user-profile class="user-profile"></data-user-profile>
</header>
<section class="content-wrapper">
<aside data-main-menu></aside>
<div class="main-content" data-ui-view></div>
</section>
<footer class="row"></footer>
login.html
(укажите ваш html для этого представления)
App.js:
var app = angular.module('npAdmin', ['ui.router']);
app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', function($httpProvider, $stateProvider, $urlRouterProvider) {
$stateProvider
.state('login',{
url:"/login",
templateUrl: '/app/login.html',
controller: 'LoginCtrl'
})
.state('main',function(){
url:"/",
templateUrl: '/app/main.html',
controller: 'MainCtrl',
abstract: true //you could use abstract state or not depending on your design
})
.state('main.dashboard', { //inherit from your main
url: '/dashboard',
templateUrl: '/app/dashboard/dashboard.html',
controller: 'DashboardCtrl'
})
.state('main.crm', { //inherit from your main
url: '/crm',
templateUrl: '/app/crm/crm.html',
controller: 'CrmCtrl'
})
Объяснение
Поскольку angular является SPA, ваш index.html должен охватывать все виды вашего приложения. Существует несколько способов обеспечить это. В этом примере login
также является состоянием в приложении, которое отделено от вашего main
. Используя наследование состояний в маршрутизаторе angular, вы можете дополнительно иметь дочерние состояния в main
, которые в этом случае dashboard
и crm
.