Angular UI Router Nested States with nested Views / Controllers - angularjs

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'
})
});

Related

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

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

AngularUI Router - Nested abstract routes not working

I'm adapting a template called Pages for an AngularJS app and I'm configuring nested view with the UI Router. It seems that everything is in place but the nested route "app/email" doesn't work, whenever it is called UI Router triggers "app/home" as the otherwise statement.
My code is this:
function($stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$urlRouterProvider
.otherwise('/app/home');
$stateProvider
.state('app', {
abstract: true,
url: '/app',
templateUrl: "tpl/app.html"
})
.state('app.home', {
url: '/home',
templateUrl: "tpl/home.html",
controller: 'HomeCtrl',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
], {
insertBefore: '#lazyload_placeholder'
})
.then(function() {
return $ocLazyLoad.load([
'assets/js/controllers/home.js'
]);
});
}]
}
})
.state('app.email', {
abstract: true,
url: '/email',
templateUrl: 'tpl/apps/email/email.html',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
'menuclipper',
'wysihtml5'
], {
insertBefore: '#lazyload_placeholder'
})
.then(function() {
return $ocLazyLoad.load([
'assets/js/apps/email/service.js',
'assets/js/apps/email/email.js'
])
});
}]
}
})
.state('app.email.inbox', {
url: '/inbox/:emailId',
templateUrl: 'tpl/apps/email/email_inbox.html'
})
.state('app.email.compose', {
url: '/compose',
templateUrl: 'tpl/apps/email/email_compose.html'
});
}
An abstract state can have child states but cannot get activated itself. An 'abstract' state is simply a state that can't be transitioned to. It is activated implicitly when one of its descendants are activated.
check this link for more details about abstract in State Provider.
you can use email state as abstract like below code.
.state('app.email', {
abstract: true,
url: '/email',
template : '<ui-view></ui-view>'
})
.state('app.email.default', {
url: '/',
templateUrl: 'tpl/apps/email/email.html',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([
'menuclipper',
'wysihtml5'
], {
insertBefore: '#lazyload_placeholder'
})
.then(function() {
return $ocLazyLoad.load([
'assets/js/apps/email/service.js',
'assets/js/apps/email/email.js'
])
});
}]
}
})
.state('app.email.inbox', {
url: '/inbox/:emailId',
templateUrl: 'tpl/apps/email/email_inbox.html'
})
.state('app.email.compose', {
url: '/compose',
templateUrl: 'tpl/apps/email/email_compose.html'
});

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#': { }
}
})

AngularJS ui-router navigate to url

I'd like to navigate to the following url through the browser:
http://localhost:9001/jira.
This only works if I add a hash to the url, like this:
http://localhost:9001/#/jira.
I tried setting the html5Mode to true, but this only removes the hash from the url. It still does not allow me to navigate directly to the url.
Here is my code:
grey.config( function( $stateProvider, $provide, $locationProvider ) {
$locationProvider.html5Mode( true ).requireBase( false );
// Set up the different views
$stateProvider
.state('index', {
url: '',
views: {
'jira_filters': {
templateUrl: 'app/partials/jira_filters.html'
},
'ciq_filters': {
templateUrl: 'app/partials/ciq_filters.html'
},
'priority': {
templateUrl: 'app/partials/priority.html'
},
'status': {
templateUrl: 'app/partials/status.html'
},
'rca': {
templateUrl: 'app/partials/rca.html'
},
}
})
.state('jira', {
url: '/jira',
views: {
'jira_filters': {
templateUrl: 'app/partials/jira_filters.html'
},
'ciq_filters': {
templateUrl: 'app/partials/ciq_filters.html'
},
'priority': {
templateUrl: 'app/partials/priority.html'
},
'status': {
templateUrl: 'app/partials/status.html'
},
'rca': {
templateUrl: 'app/partials/rca.html'
},
}
});
});

Cannot call method 'insertBefore' of null error

I'm getting this error in angularjs with ui-router. I have no idea what is setting it off and I can't track it down. Has anyone run into this before or know anything about it?
I am using yeoman with a MEAN stack (mongodb,express,angularjs,node.js). I have a feeling the error is in the states.js listed below. That is the only thing I have been working on when the error started coming up.
TypeError: Cannot call method 'insertBefore' of null
at http://localhost:9000/bower_components/angular/angular.js:3857:22
at forEach (http://localhost:9000/bower_components/angular/angular.js:303:18)
at Object.enter (http://localhost:9000/bower_components/angular/angular.js:3856:9)
at http://localhost:9000/bower_components/angular/angular.js:18828:26
at publicLinkFn (http://localhost:9000/bower_components/angular/angular.js:5443:29)
at boundTranscludeFn (http://localhost:9000/bower_components/angular/angular.js:5555:21)
at controllersBoundTransclude (http://localhost:9000/bower_components/angular/angular.js:6145:18)
at ngRepeatAction (http://localhost:9000/bower_components/angular/angular.js:18826:15)
at Object.$watchCollectionAction (http://localhost:9000/bower_components/angular/angular.js:11347:11)
at Object.applyFunction [as fn] (<anonymous>:778:50) angular.js:9101
Here is my states.js
angular.module('lifeloggerApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ui',
'ui.router'
])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/Welcome");
$stateProvider
.state('Welcome', {
url: "/Welcome",
templateUrl: "views/welcome.html"
})
.state('Welcome.About', {
url: "/about",
templateUrl: "views/about.html"
})
.state('Welcome.Contact', {
url: "/contact",
templateUrl: "views/contact.html"
})
.state('Welcome.Login', {
url: "/login",
templateUrl: "views/login.html"
})
.state('a', {
url: "/a",
views: {
'': {
templateUrl: "views/main.html",
controller: 'MainCtrl'
},
'sidebar#a': {
templateUrl: "views/sidebar.html"
}
}
})
.state('a.Dashboard', {
url: "/dashboard",
templateUrl: "views/dashboard.html"
})
.state('a.About', {
url: "/about",
templateUrl: "views/about.html"
})
.state('a.Contact', {
url: "/contact",
templateUrl: "views/contact.html"
})
.state('a.Profile', {
abstract: true,
url: "/profile",
templateUrl: "views/profile.html"
})
.state('a.Profile.UserInfo', {
url: "/userinfo",
templateUrl: "views/profile.userinfo.html"
})
.state('a.Profile.EmailPref', {
url: "/emailpref",
templateUrl: "views/profile.emailpref.html"
})
.state('a.Profile.API', {
url: "/api",
templateUrl: "views/profile.api.html"
})
.state('a.Profile.Billing', {
url: "/billing",
templateUrl: "views/profile.billing.html"
})
.state('a.Profile.Settings', {
url: "/settings",
templateUrl: "views/profile.settings.html"
})
$urlRouterProvider.when('/a/profile', '/a/profile/userinfo');
});

Resources