As Angular is SPA that's terrific, but what if I need some other page not related to index.html, how is realised by UI-Router states with different ui-views?
For example, I have 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'
})
...
Now I need login.html which is totally different from index.html (don't need index's header, footer, sidebar) but config stateProvider only looks to index.html ui-view and changes content to it by states. How to combine login.html?
It seems not that hard, but I don't get it.
As you expected, it is not so difficult, there is a plunker.
The trick is to move the common stuff for all views inside of the specific template e.g. common.html
and create the abstract state. Other words, the index.html
will remain clean:
<body>
<div ui-view=""></div>
</body>
And its previous content (content of the index.html
) would be moved to common.html
. The state definition could look like this:
$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');
What is interesting (I'd say) is that we introduced abstract state, without url. So the all current logic will remain, just the abstract will play role of a layout template.
Check more here: example
I also had this problem before, refer to THIS if you're interested. In that link, I also handled returnUrl
and 401 http status code
in case the user is not authorized.
In your case, I suggest you design your application like this:
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
(include your html for this view)
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'
})
Explanation:
As angular is SPA, your index.html should cover all views of your application. There are multiple ways to ensure that. In this example, the login
is also a state in your application that is separated from your main
. By utilizing state inheritance in angular router, you could further have child states in your main
which are dashboard
and crm
in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With