Prevent reload controller in a nested views - angularjs

I coding a modular adminpanel and only need load specific data one time.
<div id="main" ui-view>
<div ui-view="header"></div>
<div ui-view="sidebar"></div>
<!-- Start: Content-Wrapper -->
<section id="content_wrapper">
<div ui-view="topbar"></div>
<div ui-view="main"></div>
<div ui-view="footer"></div>
</section>
</div>
Topbar, header and footer should only load one time or an specific event.
I have set my states like this:
$stateProvider
.state('root', {
url: '/',
views: {
'header#': {
templateUrl: '/angular/apps/backend/views/template/header.html',
controller: 'AuthController'
},
'sidebar#':{
templateUrl: '/angular/apps/backend/views/template/sidebar.html',
controller: 'AppsController'
},
'topbar#':{
templateUrl: '/angular/apps/backend/views/template/topbar.html'
},
'footer#':{
templateUrl: '/angular/apps/backend/views/template/footer.html',
controller: ''
},
'main':{
templateUrl: '/angular/apps/backend/views/inicio.html',
controller: ''
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
.state('login', {
url: '/login',
templateUrl: '/angular/apps/backend/views/login.html',
controller: 'AuthController',
data: {
title: 'Iniciar Sesión',
bodyClass: 'external-page sb-l-c sb-r-c',
requiredLogin: false
}
})
.state('applist', {
url: '/:AppPermalink',
views: {
'header#': {
templateUrl: '/angular/apps/backend/views/template/header.html',
controller: 'AuthController'
},
'sidebar#':{
templateUrl: '/angular/apps/backend/views/template/sidebar.html',
controller: 'AppsController'
},
'topbar#':{
templateUrl: '/angular/apps/backend/views/template/topbar.html'
},
'footer#':{
templateUrl: '/angular/apps/backend/views/template/footer.html',
controller: ''
},
'main':{
templateUrl: '/angular/apps/backend/views/appresults.html',
controller: 'AppController'
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
.state('appedit', {
url: '/:AppPermalink/editar/:Itemid',
views: {
'header#': {
templateUrl: '/angular/apps/backend/views/template/header.html',
controller: 'AuthController'
},
'sidebar#':{
templateUrl: '/angular/apps/backend/views/template/sidebar.html',
controller: 'AppsController'
},
'topbar#':{
templateUrl: '/angular/apps/backend/views/template/topbar.html'
},
'footer#':{
templateUrl: '/angular/apps/backend/views/template/footer.html',
controller: ''
},
'main':{
templateUrl: function(stateParams){return '/angular/apps/backend/views/appedit_'+stateParams.AppPermalink+'.html'},
controller: 'AppController'
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
But when i change the state, the data of the sidebar has been reloaded.
I don't design a good nested views. How can doing this?

Solution found! I need use abstract state to define "sidebar", "header", "topbar" and "footer".
$stateProvider
.state('root', {
url: '',
abstract: true,
views: {
'header': {
templateUrl: '/angular/apps/backend/views/template/header.html',
controller: 'AuthController'
},
'sidebar':{
templateUrl: '/angular/apps/backend/views/template/sidebar.html',
controller: 'AppsController'
},
'topbar':{
templateUrl: '/angular/apps/backend/views/template/topbar.html'
},
'footer':{
templateUrl: '/angular/apps/backend/views/template/footer.html',
controller: ''
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
.state('root.home', {
url: '/',
views: {
'main#':{
templateUrl: '/angular/apps/backend/views/inicio.html',
controller: ''
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
.state('login', {
url: '/',
templateUrl: '/angular/apps/backend/views/login.html',
controller: 'AuthController',
data: {
title: 'Iniciar Sesión',
bodyClass: 'external-page sb-l-c sb-r-c',
requiredLogin: false
}
})
.state('applist', {
url: '/:AppPermalink',
parent: "root",
views: {
'main#':{
templateUrl: '/angular/apps/backend/views/appresults.html',
controller: 'AppController'
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
.state('appedit', {
url: '/:AppPermalink/editar/:Itemid',
parent: "root",
views: {
'main#':{
templateUrl: function(stateParams){return '/angular/apps/backend/views/appedit_'+stateParams.AppPermalink+'.html'},
controller: 'AppController'
}
},
data: {
title: 'Dashboard',
bodyClass: '',
requiredLogin: true
}
})
Controller only execute one time :)

Related

Angular ui-router $urlRouterProvider not working

function routeConfig($stateProvider, $urlRouterProvider) {
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/pages/main/main.html',
title: 'Main',
sidebarMeta: {
icon: 'ion-android-home',
order: 0,
},
}).state('main.list', {
url: '/list',
templateUrl: 'app/pages/main/list/coinList.html',
title: 'Main',
controller: 'coinListCtrl',
resolve: {
coinMarketData: function(MarketCapService) {
return MarketCapService.getCrypto();
}
}
}).state('main.detail', {
url: '/detail/:symbol',
templateUrl: 'app/pages/main/detail/coinDetail.html',
title: 'Main',
controller: "coinDetailCtrl",
});
$urlRouterProvider.when('/main','/mail/list');
}
I have one main state and two child states as main.list and main.details. Using $urlRouterProvider service i want to go to main.list state by default. But it seems the command - $urlRouterProvider.when('/main','/mail/list');
is not working at all.
The code started working when i put $urlRouterProvider.when('/main','/mail/list'); above the registration of states, like this:-
function routeConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when('/main','/mail/list');
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'app/pages/main/main.html',
title: 'Main',
sidebarMeta: {
icon: 'ion-android-home',
order: 0,
},
}).state('main.list', {
url: '/list',
templateUrl: 'app/pages/main/list/coinList.html',
title: 'Main',
controller: 'coinListCtrl',
resolve: {
coinMarketData: function(MarketCapService) {
return MarketCapService.getCrypto();
}
}
}).state('main.detail', {
url: '/detail/:symbol',
templateUrl: 'app/pages/main/detail/coinDetail.html',
title: 'Main',
controller: "coinDetailCtrl",
});
}
Though i would still like to know why? This might be due to lack of JS knowledge though, but still enlighten me..

ui-route works just the first time angularJS

i have a problems , after to have put the ui-route modal and page , i have another probleme my ui-route works just the first time and i don't know why
this is my route
angular.module('ui.bootstrap.demo').config(function($stateProvider, $urlRouterProvider,$qProvider){
$stateProvider
.state("connexion", {
url: "/",
views: {
// for column two, we'll define a separate controller
'Principal': {
abstract :true,
templateUrl: 'connexion.html'
}
}
})
.state('agenda', {
url: "/agenda",
views: {
// for column two, we'll define a separate controller
'Principal': {
abstract :true,
// templateUrl: 'agenda.html'
template:'<a ui-sref="view">Open me!</a>'
}
}
})
.state('modal', {
abstract: true,
parent: 'agenda',
url: '/modal',
onEnter: ['$uibModal', '$state', function($uibModal, $state) {
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
}
})
}]
})
.state('view', {
url: ':id1',
parent: 'modal',
views: {
'modal#': {
template: '<div class="navbar">'+
'<div class="navbar-inner">'+
'<h4 class="brand">Quick Start</h4>'+
'<ul class="nav">'+
'<li><a ui-sref="foo">Route 1</a></li>'+
'<li><a ui-sref="bar">Route 2</a></li>'+
'</ul>'+
'</div>'+
'</div>'
}
}
})
.state('foo', {
url: ':id2',
parent: 'modal',
views: {
'modal#': {
template: '<h1>foo</h1><a ui-sref="view">back menu</a>'
}
}
})
.state('bar', {
url: ':id3',
parent: 'modal',
views: {
'modal#': {
template: '<h1>bar</h1><a ui-sref="view">back menu</a>'
}
}
})
$urlRouterProvider.otherwise("/");
$qProvider.errorOnUnhandledRejections(false);
})
and this a plunker,
http://plnkr.co/edit/4D6fsQv0FiPqtjoNiebS?p=preview
if some one can help me
thanks in advance
edit
Hello guys
re edit
.state('modal', {
abstract: true,
parent: 'agenda',
url: '/modal',
onEnter: ['$uibModal', '$state', function($uibModal, $state) {
$state.go('view');
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
}
})
}]
})

Angular ui router - Share views between states

I'm trying to create a web app where I have an index.html page with three views: header, content and footer.
I'd like the header and footer to be consistent between pages but at the same time not be part of the index.html file.
I'd also like the content view to change depending on the url I've gone to.
Here is my current solution
index.html
<body>
<header ui-view="header"></header>
<main ui-view="content"></main>
<footer ui-view="footer"></footer>
</body>
app.js
$stateProvider
.state('my-app', {
abstract: true,
views: {
'header': {
templateUrl: 'partials/shared/header.html',
controller: "UserController"
},
'footer': {
templateUrl: 'partials/shared/footer.html'
}
}
})
.state('my-app.home', {
url: "/",
views: {
'content': {
templateUrl: 'partials/home.html',
controller: 'HomeController'
}
}
})
When I load the page "/" it shows the header and footer as having loaded correctly and I can see them on the page, but the main content is missing.
Can anyone tell me what I'm doing wrong?
Thanks
I managed to figure it out.
I had to get the view in my child state to point to the view in the root state explicitly.
To do that I had to point to 'content#'.
Fixed code:
app.js
$stateProvider
.state('my-app', {
abstract: true,
views: {
'header': {
templateUrl: 'partials/shared/header.html',
controller: "UserController"
},
'footer': {
templateUrl: 'partials/shared/footer.html'
}
}
})
.state('my-app.home', {
url: "/",
views: {
'content#': {
templateUrl: 'partials/home.html',
controller: 'HomeController'
}
}
})
You need a parent for my-app.home :
.state('my-app.home', {
parent: 'my-app',
url: "/",
views: {
'content': {
templateUrl: 'partials/home.html',
controller: 'HomeController'
}
}
}
Try this:
$stateProvider
.state('my-app', {
abstract: true,
views: {
'header': {
templateUrl: 'partials/shared/header.html',
controller: "UserController"
},
'content': {
template: '<ui-view/>',
},
'footer': {
templateUrl: 'partials/shared/footer.html'
}
}
})
.state('my-app.home', {
url: "/",
templateUrl: 'partials/home.html',
controller: 'HomeController'
})

Create states from array object in Angular ui-router

I am able to create a state from an object like so...
var stateTest = {
name: '2',
views: {
'video': {
templateUrl: 'templates/2_video.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
};
$stateProvider.state(stateTest);
but what I need to do is create states from an array. This was my attempt and it is not working.
var stateList = [
{
name: '3',
views: {
'video': {
templateUrl: 'templates/3.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
},{
name: '4',
views: {
'video': {
templateUrl: 'templates/4.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
}
];
$stateProvider.state(stateList);
Then I thought I needed to try the foreach item approach...
var stateList = [
{
name: '3',
templateUrl: 'templates/3.html',
controller: 'VideoCtrl',
template: 'content'
},{
name: '4',
templateUrl: 'templates/4.html',
controller: 'VideoCtrl',
template: 'content'
},
];
stateList.forEach(function (item) {
VideoTest.stateProvider.state(item[0],{
views: {
'video': {
templateUrl: item[1],
controller: item[2]
},
'content': {
template: item[3],
controller: item[2]
}
}
});
});
Still no good :( Ideas!?
------- EDIT ------
As Craig pointed out in the answer, my array call was jacked up but I also didn't need to call the main module, but rather just place this in a module config like so:
VideoTest.config(function($stateProvider) {
var stateList = [
{
name: '3',
views: {
'video': {
templateUrl: 'templates/3.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
},{
name: '4',
views: {
'video': {
templateUrl: 'templates/4.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
}
];
stateList.forEach(function (item) {
$stateProvider.state(item.name,{
views: {
'video': {
templateUrl: item.views.video.templateUrl,
controller: item.views.video.controller
},
'content': {
template: item.views.content.template,
controller: item.views.content.controller
}
}
});
});
});
Your problem with your forEach implementation is indexing the item[0]. The item passed to the forEach callback (i.e. arg[0]) is the element itself so indexing this as an array doesn't make sense.
Your data:
var stateList = [
{
name: '3',
views: {
'video': {
templateUrl: 'templates/3.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
},{
name: '4',
views: {
'video': {
templateUrl: 'templates/4.html',
controller: 'VideoCtrl'
},
'content': {
template: '{{content}}',
controller: 'VideoCtrl'
}
}
}
];
and state setup:
stateList.forEach(function (item) {
VideoTest.stateProvider.state(item.name,{
views: {
'video': {
templateUrl: item.views.video.templateUrl,
controller: item.views.video.controller
},
'content': {
templateUrl: item.views.content.templateUrl,
controller: item.views.content.controller
}
}
});
});

New ui-router states are not created

I have this code (inherited an app)
angular.module('somename').
config(function($stateProvider, $urlRouterProvider) {
$stateProvider.
/**
* Login Form State
**/
state('login', {
url: '/login',
templateUrl: 'views/login.tpl.html',
controller: 'loginCtrl',
authenticate: false,
bodyClass: 'login'
}).
/**
* Root View, Sees Widgets States
*/
state('logged-in', {
url: '/',
templateUrl: 'views/logged-in-root.tpl.html',
controller: 'rootCtrl',
authenticate: true,
bodyClass: 'home'
}).
/**
* The Search Form States
*/
state('logged-in.search', {
url: 'search',
authenticate: true,
bodyClass: 'search',
pageTitle: 'Search | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/search/search.tpl.html',
controller: 'searchCtrl'
}
}
}).
/**
* List of Results States
*/
state('logged-in.results', {
url: 'results',
authenticate: true,
bodyClass: 'results',
pageTitle: 'Results | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/results/results.tpl.html',
controller: 'resultsCtrl'
}
}
}).
/**
* Viewing All Profiles States
*/
// List of all profiles without specific selected
state('logged-in.result-all', {
url: 'result',
authenticate: true,
bodyClass: 'result',
pageTitle: 'Result | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/result/result.tpl.html',
controller: 'resultCtrl'
}
}
}).
// Adding a new profile
state('logged-in.result-all.new-profile', {
url: '/profile/new',
authenticate: true,
bodyClass: 'new-profile',
pageTitle: 'New Profile | Crowdskout',
templateUrl: 'views/result/new-profile.tpl.html',
controller: 'newProfileCtrl'
}).
// Specific profile selected
state('logged-in.result-all.profile', {
url: '/profile/:profileId',
authenticate: true,
bodyClass: 'profile',
pageTitle: 'Profile | Crowdskout',
templateUrl: 'views/result/profile.tpl.html',
controller: 'profileCtrl'
}).
/**
* Viewing a Specific Result Set States
*/
// List of all the matching profiles without a specific profile selected
state('logged-in.result', {
url: 'result/:resultId',
authenticate: true,
bodyClass: 'result',
pageTitle: 'Result | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/result/result.tpl.html',
controller: 'resultCtrl'
}
}
}).
// Adding a new profile while viewing a specific result set
state('logged-in.result.new-profile', {
url: '/profile/new',
authenticate: true,
bodyClass: 'new-profile',
pageTitle: 'New Profile | Crowdskout',
templateUrl: 'views/result/new-profile.tpl.html',
controller: 'newProfileCtrl'
}).
// Viewing a specific profile within a result set
state('logged-in.result.profile', {
url: '/profile/:profileId',
authenticate: true,
bodyClass: 'profile',
pageTitle: 'Profile | Crowdskout',
templateUrl: 'views/result/profile.tpl.html',
controller: 'profileCtrl'
}).
/**
* Taking Action on a Specific Result Set
**/
state('logged-in.actions', {
url: 'result/:resultId/action',
authenticate: true,
bodyClass: 'actions',
pageTitle: 'Take Action | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/actions/action.tpl.html',
controller: 'actionCtrl'
}
}
}).
// Exporting to File
state('logged-in.actions.export', {
url: '/export',
authenticate: true,
bodyClass: 'actions export',
pageTitle: 'Export List | Crowdskout',
views: {
'modal#logged-in' : {
templateUrl: 'views/actions/export.tpl.html',
controller: 'exportCtrl'
}
}
}).
// Email list
state('logged-in.actions.email', {
url: '/email',
authenticate: true,
bodyClass: 'actions email',
pageTitle: 'Email List | Crowdskout',
views: {
'modal#logged-in' : {
templateUrl: 'views/actions/email.tpl.html',
controller: 'emailCtrl'
}
}
}).
/**
* States for viewing and managing user accounts
**/
// View all accounts
state('logged-in.accounts', {
url: 'accounts',
authenticate: true,
bodyClass: 'accounts',
pageTitle: 'Accounts | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/account/accounts.tpl.html',
controller: 'accountsCtrl'
}
}
}).
// Create new account
state('logged-in.new-account', {
url: 'account/new',
authenticate: true,
bodyClass: 'new-account',
pageTitle: 'New Account | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/account/new-account.tpl.html',
controller: 'newAccountCtrl'
}
}
}).
// View a specific account
state('logged-in.account', {
url: 'account/:accountId',
authenticate: true,
bodyClass: 'account',
pageTitle: 'Account | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/account/account.tpl.html',
controller: 'accountCtrl'
}
}
}).
/**
* States for viewing and managing outside connections
**/
state('logged-in.connect', {
url: 'connect',
authenticate: true,
bodyClass: 'connect',
pageTitle: 'Connect | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/connect/index.tpl.html'
}
}
}).
// View and update Mailchimp accounts
state('logged-in.connect.mailchimp', {
url: '/mailchimp',
authenticate: true,
bodyClass: 'connect mailchimp',
pageTitle: 'Mailchimp | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/connect/mailchimp.tpl.html'
}
}
}).
state('logged-in.connect.import', {
url: '/import',
authenticate: true,
bodyClass : 'connect import',
pageTitle: 'Import List | Crowdskout',
views: {
'main#logged-in' : {
templateUrl: 'views/connect/import.tpl.html'
}
}
}).
state('logged-in.client', {
url: '/client',
authenticate: true,
bodyClass : 'client',
views: {
'main#logged-in' : {
templateUrl:'views/client/index.tpl.html'
}
}
});
$urlRouterProvider.otherwise('/login');
});
The last url client isn't coming up. It redirects to login.
Thanks
Try changing to url property of the last route to get rid of the extra slash.
state('logged-in.client', {
url: 'client',
authenticate: true,
bodyClass : 'client',
views: {
'main#logged-in' : {
templateUrl:'views/client/index.tpl.html'
}
}
})
If you try an url like baseUrl/asdfasd it will take you to /login and that is written here:
$urlRouterProvider.otherwise('/login');
Take a look if your link is
ui-sref="logged-in.client"
Also try in 'client' instead of '/client'
We can't tell anything else without more code.

Resources