angularjs - ui-router not displaying properly ($stateProvider) - angularjs

I'm trying to set up my app. It was working fine, but then I had to change some URLs on the ui-router in order to have some sub-views.
Unfortunately, now, I cannot see all my pages properly and I don't understand why.
Here's an example: http://codepen.io/anon/pen/LNQavV?editors=1010
Basically, I have different templates, and when URL changes, I display a different template into appContent view. Inside my details, I need to have a subView called zone, in which I can display detailsOverview template or detailsEdit template.
With my current setup,I'm not able to change page. Well, the page changes according to the URL, but detailsOverview is always displayed!
I think that the problem is somehow related with the subview rather than the URLs, but not 100% sure.
I'm pasting $stateProvider code here as well:
angular.module('ionicApp', ['ionic']).config([
'$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider.state('app', {
name: 'app',
url: '/app',
abstract: true,
templateUrl: 'templates/menuTemplate.html'
}).state('app.details', {
name: 'appDetails',
url: '/:zoneID',
views: {
'appContent': {
templateUrl: 'templates/mainDetails.html'
}
}
}).state('app.details.overview', {
name: 'appDetailsOverview',
url: '/details',
views: {
'appContent': {
templateUrl: 'templates/mainDetails.html'
},
'zone': {
templateUrl: 'templates/detailsOverview.html'
}
}
}).state('app.details.edit', {
name: 'appDetailsEdit',
url: '/edit/day/:timerEditDay',
views: {
'appContent': {
templateUrl: 'templates/mainDetails.html'
},
'zone': {
templateUrl: 'templates/detailsEdit.html'
}
}
}).state('app.setup', {
name: 'setup',
url: '/setup',
views: {
'appContent': {
templateUrl: 'templates/setup.html'
}
}
}).state('app.about', {
name: 'about',
url: '/about',
views: {
'appContent': {
templateUrl: 'templates/about.html',
controller: 'aboutPageInfo'
}
}
});
$urlRouterProvider.otherwise('app/');
}
]);

The problem is that with the url: '/:zoneID', in the app.details state you "swallow" all the possible parameters.
Thats means the url #/app/about and #app/setup URLs get also handled by the app.details state and don't seem to work.
In order to get them working, you have to define the app.about and app.setup state before the app.details state:
$stateProvider.state('app', {
name: 'app',
url: '/app',
abstract: true,
templateUrl: 'templates/menuTemplate.html'
}).state('app.setup', {
name: 'setup',
url: '/setup',
views: {
'appContent': {
templateUrl: 'templates/setup.html'
}
}
}).state('app.about', {
name: 'about',
url: '/about',
views: {
'appContent': {
templateUrl: 'templates/about.html',
controller: 'aboutPageInfo'
}
}
}).state('app.details', {
name: 'appDetails',
url: '/:zoneID',
views: {
'appContent': {
templateUrl: 'templates/mainDetails.html'
}
}
}).state('app.details.overview', {
name: 'appDetailsOverview',
url: '/details',
views: {
'appContent': {
templateUrl: 'templates/mainDetails.html'
},
'zone': {
templateUrl: 'templates/detailsOverview.html'
}
}
})
See the updated codepen with a working details and setup page:
http://codepen.io/anon/pen/BKPyMd?editors=1010

Related

Failed to load resource: net::ERR_FILE_NOT_FOUND in ionic

I am very new to ionic and angularjs. When I run my application in browser it works fine but after build for android and run it in devices i get blank page. And when i check console using I get the following error.
And this is my code
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$stateProvider.state('index', {
url: '/',
views: {
'page_sidemenu': {
templateUrl: "index_sidemenu.html"
},
'page_content': {
templateUrl: "main_page.html"
}
}
});
$stateProvider.state('home', {
url: '/home',
views: {
'page_sidemenu': {
templateUrl: 'profile_sidemenu.html',
controller: 'profilemenuCtr'
},
'page_content': {
templateUrl: 'profile_page.html',
controller: 'profileCtr'
}
}
});
$stateProvider.state('login', {
url: "/login?id",
views: {
'page_sidemenu': {
templateUrl: "index_sidemenu.html"
},
'page_content': {
templateUrl: "login_page.html",
controller: "loginCtr"
}
}
});
$urlRouterProvider.otherwise('/');
Anybody please help me to resolve this.

Controller reloading on ui router state change

I'm having a problem I can't seem to figure out. When using ui-sref to change to a new state, the correct controller "does" load, but the current controller ALSO reloads. Twice in fact. (I set a break-point in the JavaScript and it hits that break-point twice).
Here is the relevant UI-router code:
.state('index',
{
abstract: true,
url: "/index",
templateUrl: "app/shared/content.html"
})
.state('index.cardholder',
{
url: '/cardholder',
views: {
'content': {
templateUrl: 'app/views/cardholder/cardholder.html',
controller: 'cardholderController'
}
},
resolve: {
loadPlugin: function ($ocLazyLoad) {
return $ocLazyLoad.load([
{
name: 'app',
files: ['app/views/cardholder/cardholderController.js']
}
]);
}
},
params: {
loadParams: false
}
})
.state('index.cardholderedit',
{
url: '/cardholder/edit',
views: {
'content': {
templateUrl: 'app/views/cardholder/edit/editCardholder.html',
controller: 'editCardholderController'
}
},
resolve: {
loadPlugin: function ($ocLazyLoad) {
return $ocLazyLoad.load([
{
name: 'app',
files: ['app/views/cardholder/edit/editCardholderController.js']
}
]);
}
},
params: {
id: null,
template: null
}
})
And here is the sref that calls the new state:
<a ui-sref="index.cardholderedit({ id:cardholder.empPersonDTO.personId, template:selectedTemplate})">
I did a search on cardholderController just to make sure I didn't have a naming issue somewhere - it all looks kosher.
Why is cardholderController reloading? How do I stop it?

Angular UI Router Nested States with nested Views / Controllers

Trying to find a way to load both nested state views and controllers under a parent view and controller. I have it successfully routing, but it doesn't load the nested template or the controller.
Appreciate the help!
stateHelperProvider.state({
name: 'artist',
url: '/' + artistSlug,
abstract: true,
resolve: {
artist: ['appArtist', function(appArtist) {
return app.getArtist();
}]
},
children: [
{
name: 'events',
url: '/',
templateUrl: "/templates/events/events.html",
controller: "eventsCtrl",
parent: 'artist'
},
{
name: 'extra-info',
url: '/extra-info',
templateUrl: "/templates/extra-info.html",
parent: 'artist'
},
{
name: 'articles',
url: '/articles',
templateUrl: "/templates/articles/articles.html",
controller: "articlesCtrl",
parent: 'artist'
}
]
});
You can do it as follows:
var myApp = angular.module('angularApp', ['ui-router'])
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('artist', {
url: '/artist',
templateUrl: 'xxxxx',
controller: 'xxxxCtrl'
})
.state('artist.events', {
url: '/events',
templateUrl: '/templates/events/events.html',
controller: 'eventsCtrl'
})
.state('artist.extra-info', {
url: '/extra_info',
templateUrl: '/templates/extra-info.html'
})
.state('artist.articles', {
url: '/articles',
templateUrl: '/templates/articles/articles.html',
controller:'articlesCtrl'
})
});
(or)
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('artist', {
url: '/artist',
templateUrl: 'xxxxx',
controller: 'xxxxCtrl'
})
.state('events', {
url: '/events',
parent:'artist',
templateUrl: '/templates/events/events.html',
controller: 'eventsCtrl'
})
.state('extra-info', {
url: '/extra_info',
parent:'artist',
templateUrl: '/templates/extra-info.html'
})
.state('articles', {
url: '/articles',
parent:'artist',
templateUrl: '/templates/articles/articles.html',
controller:'articlesCtrl'
})
});

AngularJS UI-Router default views

Here's the example code.
http://plnkr.co/edit/jXEQ9xemL1A5b9KKKcAw?p=preview
var app = angular.module('npAdmin', ['ui.router']);
app.config(['$httpProvider', '$stateProvider', '$urlRouterProvider',
function($httpProvider, $stateProvider, $urlRouterProvider) {
$stateProvider
.state('common', {
templateUrl: 'tpl.common.html',
abstract: true,
// views: {
// 'footer': {
// templateUrl: 'footer.html'
// }
// }
})
.state('common.dashboard', {
url: '/dashboard',
views: {
'content': {
template: '<div><h4>dashboard</h4></div>'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('common.crm', {
url: '/crm',
views: {
'content': {
template: '<div><h4>CRM</h4></div>'
},
'footer': {
templateUrl: 'footer.html'
}
}
})
.state('common.abc', {
url: '/abc',
views: {
'content': {
template: '<div><h4>ABC</h4></div>'
},
'footer': {
templateUrl: 'newfooter.html'
}
}
})
.state('landing', {
templateUrl: 'tpl.login.html',
abstract: true,
})
.state('landing.login', {
url: '/login',
template: '<div><h4>Wow</h4></div>',
});
$urlRouterProvider.otherwise('/crm');
}
]);
The default 'templateUrl' of 'footer' is 'footer.html', but it's 'newfooter.html' for some state.
Is there a good way to set default footer in this case?
I tried to use 'templateUrl' and 'views' at the same time, but it doesn't work.
There is updated plunker. We can use absolute naming in the parent 'common':
.state('common', {
abstract: true,
views: {
'': {
templateUrl: 'tpl.common.html',
},
'footer#common': {
templateUrl: 'footer.html'
}
}
})
And override it only if needed ('dashboard' and 'crm' will use the parent footer, while the 'abc' is defining an override - special one: newfooter.html)
.state('common.dashboard', {
url: '/dashboard',
views: {
'content': {
template: '<div><h4>dashboard</h4></div>'
},
// provided by parent
//'footer': {
// templateUrl: 'footer.html'
//}
}
})
.state('common.crm', {
url: '/crm',
views: {
'content': {
template: '<div><h4>CRM</h4></div>'
},
// provided by parent
//'footer': {
// templateUrl: 'footer.html'
//}
}
})
.state('common.abc', {
url: '/abc',
views: {
'content': {
template: '<div><h4>ABC</h4></div>'
},
'footer': {
templateUrl: 'newfooter.html'
}
}
Check it here
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})

Angular UI Router multiple/named routes

I have a user layout file that is the template for any user pages:
<div class="user-wrapper">
<div ui-view="menu"></div>
<div ui-view="content"></div>
</div>
Depending on the state I want the menu to be different. Such as:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/one.html" }
},
});
.state('user.two', {
url: '/two',
controller: 'twoController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/two.html" }
},
});
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
},
});
Now you can see "one" and "two" both use the same menu but "three" uses a different menu. This all works fine but is there a way to avoid duplicating the menu on "one" and "two".
Such as making a "user.client" state that uses the "user-menu.html" then "one" would be "user.client.one" instead and only have to specify the content.
I think the main problem is the
<div ui-view="content"></div>
is on the grandfather of the "user.client.one" so how can it specify the content?
I would say, that the trick is to move the "menu" view definition into parent state "user"
.state('user', {
url: '/user',
views: {
"" : {
templateUrl: 'partials/user.html',
controller: 'userController',
},
"menu#user": { templateUrl: "partials/client-menu.html" },
},
...
So, what happened? any child state of the "user" will already have the content of the "menu" filled, with the default templateUrl: "partials/client-menu.html"
Any other child, can override that...
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
// "menu": already set by parent
"content": { templateUrl: "partials/one.html" }
....
.state('user.two', {
url: '/two',
views: {
// "menu": set in parent
"content": { templateUrl: "partials/two.html" }
...
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
// here we override that
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
...
Maybe, check this Q & A for some more ideas about multi view nesting:
multiple ui-view html files in ui-router
AngularJS ui-router view structure product site
I think a found a solution user the # for absolute views:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.client', {
url: '/client',
views: {
"menu": { templateUrl: "partials/client-menu.html" }
},
})
.state('user.admin', {
url: '/admin',
views: {
"menu": { templateUrl: "partials/admin-menu.html" }
},
})
.state('user.client.one', {
url: '/one',
controller: 'oneController',
views: {
"content#user": { templateUrl: "partials/one.html" }
},
});
.state('user.client.two', {
url: '/two',
controller: 'twoController',
views: {
"content#user": { templateUrl: "partials/two.html" }
},
});
.state('user.admin.three', {
url: '/three',
controller: 'threeController',
views: {
"content#user": { templateUrl: "partials/three.html" }
},
});
It feels abit cleaner but I'm not sure if its the right approach still.

Resources