Converting a ngRoute based AngularJS app to Angular ui-router

My AngularJS app I’ve been developing for a while was using ngRoute for it’s routing between views (I put together a simple example for reference on GitHub here). I got to the point where I need more that just single URL based routes to views, I needed to have at least one of the views incorporate other nested views that are part of a wizard set of pages. This is something that’s not supported by default in ngRoute, so I’m taking a look at AngularJS ui-router as an alternative.

AngularUI Router is state based, rather than that URL based.

Here’s my starting point for my app before adding the nested views and converting to ui-router:

[code]
var myApp = angular.module(‘MyApp’, [ "ngRoute", "ngAnimate",
"MyControllers" ]);

myApp.config([ ‘$routeProvider’, function($routeProvider{
$routeProvider.when(‘/’, {
templateUrl : ‘home.html’
}).when(‘/page1’, {
templateUrl : ‘page1/page1.html’,
controller : ‘Page1Controller’
}).when(‘/page2’, {
templateUrl : ‘page2.html’
}).when(‘/page3’, {
templateUrl : ‘page3.html’
}).otherwise({
redirectTo : ‘/’
});
}]);
[/code]

Converted to the state based approach, my routing config now looks like:

[code]
var myApp = angular.module(‘MyApp’, [ "ui.router", "ngAnimate", "MyControllers" ]);

myApp.config(function($stateProvider, $urlRouterProvider) {

$stateProvider
// show home page
.state(‘home’, {
url: ‘/home’,
templateUrl: ‘home.html’
})

//show page2
.state(‘page2’, {
url: ‘/page2’,
templateUrl: ‘page2/page2.html’,
controller: ‘Page2Controller’
})

//show page3
.state(‘page3’, {
url: ‘/page3’,
templateUrl: ‘page3.html’
})

// catch all route
// send users to the home page
$urlRouterProvider.otherwise(‘/home’);
});[/code]

The ng-view from ngRoute is now replaced with the ui-view directive from ui-router:

[code]
<div ng-view></div>
[/code]

becomes:

[code]
<div ui-view></div>
[/code]

My menu links looked like this previously:

[code]
<li><a href="index.html#/home">Home</a></li>
<li><a href="index.html#/page1">Page 1</a></li>
<li><a href="index.html#/page2">Page 2</a></li>
[/code]

 

Instead of using URLs that map to view templates, ui-router uses states and state changes to move between page templates – here’s what the replacement for the above menu links looked like:

[code]
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="page1">Page 1</a></li>
<li><a ui-sref="page2">Page 2</a></li>
[/code]

Right now the routing configuration is really not that much different than before: the ui-router config is slightly different and ui-sref states replaced the links. Where the interesting part is that now you can also support nested views, that look like this in the configuration:

[code]
$stateProvider
// show page2
.state(‘page2’, {
url: ‘/page2’,
templateUrl: ‘page2/page2.html’
})

//show page2 – sub page1
.state(‘page2.subsection1’, {
url: ‘/page2/sub1’,
templateUrl: ‘page2/page2sub1.html’
})

//show page2 – sub page2
.state(‘page2.subsection2’, {
url: ‘/page2/sub2’,
templateUrl: ‘page2/page2sub2.html’
})
[/code]

This is the routing for page2 and two nested views that are nested within the main ui-view (ui-view is the ui-router replacement for ng-view ) with a states of page2.subsection1 and page2.subsection2.

The nested views have corresponding nested states in the routing, identified with a dot notation. Assuming page 2 has a submenu and it’s own ui-view nested view, the submenu would like like this:

[code]
<li><a ui-sref="page2.subsection1">Subsection 1</a></li>
<li><a ui-sref="page2.subsection2">Subsection 2</a></li>
[/code]

With a following ui-view nested view in the page following the Page 2’s submenu:

[code]
<div ui-view></div>
[/code]

… clicking on the submenu items will load the nested view fragments into this nested view.

Full docs for ui-router are here.

I have two working sample apps showing an approach using ngRouter and then the examples above updates to use ng-router:

  • Using ng-route here
  • Using ui-router here