Tim Kindberg
Front-End Developer
Nested Views and Routing for Angularjs
Overview for CincyNg Meetup
Union of Rad
Graphic Designer turned
eLearning Course Designer turned
Flash Animator turned
Flash/Flex Developer turned
Web UI/UX Designer turned
Front-end Web Developer turned ?
Researching JavaScript frameworks for project.
Angular: Easy, Fun, Familiar
UI-Router's solution
$stateProvider.state('contact.detail', {
url: '/contacts/:id',
template: '<h1>Hello</h1>',
templateUrl: 'contacts.html',
controller: function($scope){ ... },
resolve: { ... }
})
$routeProvider.when('/contacts/:id', {
template: '<h1>Hello</h1>',
templateUrl: 'contacts.html',
controller: function($scope){ ... },
resolve: { ... }
})
ngRoute
ui.router
Main method of adding routes
1.2 changes to route()
Just for creating url redirects
To use when or otherwise, $urlRouterProvider
$urlRouterProvider
.when('/user/:id', '/contacts/:id') .otherwise('/');
index.html
<body>
<ui-view/>
</body>
app.js
.state('top', { template:"<ui-view/>"
}) .state('top.middle', { template:" <ui-view/>"
<ui-view/>" }) .state('top.middle.bottom', { template:"
})
How baby states are made.
$stateProvider
.state("home", { ... });
.state("contacts", { ... });
.state("contacts.detail", { ... });
.state("contacts.detail.edit", { ... });
The dot in the state names auto-denotes parental hierarchy.
It knows that 'contacts.detail' is a child of 'contacts'.
1. $stateProvider
.state('contacts', {}) .state('contacts.list', {});
2. $stateProvider
.state('contacts', {}) .state('list', { parent: 'contacts' });
var contacts = {
name: 'contacts', //mandatory
templateUrl: 'contacts.html'
}
var contactsList = {
name: 'list', //mandatory
parent: contacts, //mandatory
templateUrl: 'contacts.list.html'
}
$stateProvider
.state(contacts)
.state(contactsList)
.state('parent', {
resolve:{
resA: function(){
return {'value': 'A'};
}
},
controller: function($scope, resA){
$scope.resA = resA.value;
}
})
.state('parent.child', {
resolve:{
resB: function(resA){
return {'value': resA.value + 'B'};
}
},
controller: function($scope, resA, resB){
$scope.resA2 = resA.value;
$scope.resB = resB.value;
}
$stateProvider
.state('parent', { data:{ customData1: "Hello", customData2: "World!" } }) .state('parent.child', { data:{ // customData1 inherited from 'parent' // but we'll overwrite customData2 customData2: "UI-Router!" } }); $rootScope.$on('$stateChangeStart', function(event, toState){ var greeting = toState.data.customData1 + " " + toState.data.customData2; console.log(greeting); })
When 'parent' is activated it prints 'Hello World!'
When 'parent.child' is activated it prints 'Hello UI-Router!'
$stateProvider.state("contacts", {
template: '<h1>{{title}}</h1>',
resolve: { title: 'My Contacts' },
controller: function($scope, title){
$scope.title = 'My Contacts';
},
onEnter: function(title){
if(title){ ... do something ... }
},
onExit: function(title){
if(title){ ... do something ... }
}
})
myApp.controller('contactCtrl', ['$scope', '$state',
function($scope, $state){
$scope.goToDetails = function(){
$state.go('contact.details', {id: selectedId});
}
}
Go to parent - $state.go('^')
Go to child - $state.go('.3')
Go to sibling - $state.go('^.1')
Absolute Path - $state.go('3.3')
Hey Cous! - $state.go('^.^.2.1')
<a ui-sref="home">Home</a>
<a ui-sref="home" href="#/home">Home</a>
<li ng-repeat="contact in contacts">
<a ui-sref="contacts.detail({ id: contact.id })"</a>
</li>
<a ui-sref='^'>Home</a>
In theory...
one could build an app using ui-router that associated not a single url with any state. They could navigate via go() and ui-sref....In theory.
$stateProvider
.state('contacts', {
url: '/contacts',
})
.state('contacts.list', {
url: '/list',
});
$stateProvider
.state('contacts', {
url: '/contacts',
})
.state('contacts.list', {
url: '^/list',
});
url: '/contacts/:contactId'
url: '/contacts/{contactId}'
url: '/contacts/{contactId:[0-9a-fA-F]{1,8}}' //Hexadecimals
url: '/contacts?contactId&contactRegion' //Separate with '&'
//State URL:
url: '/users/:id/details/{type}/{repeat:[0-9]+}?from&to'
//Navigate to:
'/users/123/details//0' //$stateParams will be
{ id:'123', type:'', repeat:'0' }
//Navigated to:
'/users/123/details/default/0?from=there&to=here'
//$stateParams will be
{ id:'123', type:'default', repeat:'0',
from:'there', to:'here' }
$stateProvider.state('contacts.detail', {
url: '/contacts/:contactId',
resolve: { depA: function(){
return $state.current.params.contactId + "!" };
}, controller: function($stateParams){ $stateParams.contactId // Exists! }
}).state('contacts.detail.subitem', { url: '/item/:itemId', controller: function($stateParams){ $stateParams.contactId // Doesn't exist $stateParams.itemId // Exists!
} })
{ name: '', url: '^', 'abstract': true
}
$stateProvider
.state('deep.down.state.mainbits', {
url: "url/still/goes/up/here"
views: {
'main@': { ... },
'sidenav@': { ... }
}
})
$stateProvider .state('report', { url: "url/still/goes/up/here" views: { 'main': { ... }, 'sidenav': {
templateUrl: "sidenav.html",
controller: "SideNavCtrl"
} } })
By Tim Kindberg
UI-Router is an angularjs replacement module for ngRoute. It builds upon ngRoute's features by adding nested views and states capabiliites as well as the ability to have multiple named views at any level in the state tree.