Reputation: 31
I have single page angularjs app using nested named views with ui-router and it's working, but there is lots of duplicated code when defining states, but I'm not sure of the best way to approach the problem. In the declaration of the states below I'm having to repeat all the views, where the only change is the name of the template and controller in the 'page-view'. The 'login-status-view', 'site-status-view', 'debug-view' all remain the same. I want to remove this duplication and only define the exceptions to the rule.
I have tried regular expression, but I can't get it to work, and I have read [question]: AngularJS - Router UI - Defining a wildcard parented state This might be an option, to run through a list of the common pages and define each state. Before I proceeded I wanted to make sure I was approaching this the 'correct' way. Use Regular expression and if so how, or run through a loop to define the states, or something else I'm missing.
The page html:
<!--Simplified html: named ui-views defined-->
<div data-ng-controller="mainCtrl as vm">
<div class="container body-content">
<div ui-view="login-status-view"></div>
<div ui-view="site-status-view"></div>
<div ui-view="page-view"></div>
<div ui-view="debug-view"></div>
</div>
</div>
The state provider states are defined here:
$stateProvider
.state('home', {
url: '/home',
views: {
"page-view": { templateUrl: 'pages/partial/home.html' }
, "login-status-view": { templateUrl: 'pages/partial/login.display.html' }
, "site-status-view": { templateUrl: 'pages/partial/status.display.html' }
,"debug-view": { templateUrl: 'pages/debug/debug.details.html', controller: 'debug.details' }
}
})
.state('about', {
url: '/about',
views: {
"page-view": { templateUrl: 'pages/partial/about.html' }
, "login-status-view": { templateUrl: 'pages/partial/login.display.html' }
, "site-status-view": { templateUrl: 'pages/partial/status.display.html' }
, "debug-view": { templateUrl: 'pages/debug/debug.details.html', controller: 'debug.details' }
}
})
.state('contact', {
url: '/contact',
views: {
"page-view": { templateUrl: 'pages/partial/contact.html' }
, "login-status-view": { templateUrl: 'pages/partial/login.display.html' }
, "site-status-view": { templateUrl: 'pages/partial/status.display.html' }
, "debug-view": { templateUrl: 'pages/debug/debug.details.html', controller: 'debug.details' }
}
})
// more pages inserted here, all with their own templates and some with their own controllers
// ...
//
// register, login and logout pages, each with their own template and controller
.state('register', {
url: '/register',
views: {
"page-view": { templateUrl: 'pages/partial/account.register.html', controller: 'account.register' }
, "login-status-view": { templateUrl: 'pages/partial/login.display.html' }
, "site-status-view": { templateUrl: 'pages/partial/status.display.html' }
, "debug-view": { templateUrl: 'pages/debug/debug.details.html', controller: 'debug.details' }
}
})
.state('login', {
url: '/login',
views: {
"page-view": { templateUrl: 'pages/partial/account.login.html', controller: 'account.login' }
, "login-status-view": { templateUrl: 'pages/partial/login.display.html' }
, "site-status-view": { templateUrl: 'pages/partial/status.display.html' }
, "debug-view": { templateUrl: 'pages/debug/debug.details.html', controller: 'debug.details' }
}
})
.state('logout', {
url: '/logout',
views: {
"page-view": { templateUrl: 'pages/partial/account.logout.html', controller: 'account.logout' }
, "login-status-view": { templateUrl: 'pages/partial/login.display.html' }
, "site-status-view": { templateUrl: 'pages/partial/status.display.html' }
, "debug-view": { templateUrl: 'pages/debug/debug.details.html', controller: 'debug.details' }
}
});
// there are some other pages not included here, but that follow a similar format
Upvotes: 2
Views: 1425
Reputation: 3108
Have all the common views in an abstract parent state.
Will look something like this, with your page-view template being a placeholder for the template of a child state.
.state('shell', {
abstract: true,
views: {
"page-view": { template: '<div ui-view></div>' } // THIS IS WHERE THE CHILD (PAGE) VIEWS WILL BE RENDERED
, "login-status-view": { template: '<div>This is the login status view</div>' }
, "site-status-view": { template: '<div>This is the site status view</div>' }
, "debug-view": { template: '<div>This is the debug view</div>' }
}
})
.state('shell.home', {
url: '/home',
template: '<div class="purple">This is the home view</div>'
})
.state('shell.about', {
url: '/about',
template: '<div class="green">This is the about view</div>'
})
.state('shell.contact', {
url: '/contact',
template: '<div class="blue">This is the contact view</div>'
})
.state('shell.register', {
url: '/register',
template: '<div class="pink">This is the register view</div>'
})
.state('shell.login', {
url: '/login',
template: '<div class="orange">This is the login view</div>'
})
.state('shell.logout', {
url: '/logout',
template: '<div class="red">This is the logout view</div>'
});
Upvotes: 1