You want nice looking URLs and can provide server-side support.
We will use the same example but use the Express framework to serve all content and handle the URL rewriting.
Let us start with the route configuration:
app.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when("/persons",
{ templateUrl: "/partials/index.jade",
controller: "PersonIndexCtrl" }).
when("/persons/:id",
{ templateUrl: "/partials/show.jade",
controller: "PersonShowCtrl" }).
otherwise( { redirectTo: "/persons" });
});
There are no changes except for the html5Mode
method, which enables our new routing mechanism. The Controller implementation does not change at all.
We have to take care of the partial loading though. Our Express
app will have to serve the partials for us. The initial typical boilerplate for an Express
app loads the module and creates a server:
var express = require('express');
var app = module.exports = express.createServer();
We will skip the configuration here and jump directly to the server-side route definition:
app.get('/partials/:name', function (req, res) {
var name = req.params.name;
res.render('partials/' + name);
});
The Express
route definition loads the partial with given name from the partials
directory and renders its content.
When supporting HTML5 routing, our server has to redirect all other URLs to the entry point of our application, the index
page. First we define the rendering of the index
page, which contains the ng-view
directive:
app.get('/', function(req, res) {
res.render('index');
});
Then the catch all route which redirects to the same page:
app.get('*', function(req, res) {
res.redirect('/');
});
Let us quickly check the partials again. Note that they use the Jade template engine, which relies on indentation to define the HTML document:
p This is the index partial
ul(ng-repeat="person in persons")
li
a(href="/persons/{{person.id}}"){{person.name}}
The index page creates a list of persons and the show page shows some more details:
h3 Person Details {{person.name}}
p Age: {{person.age}}
a(href="/persons") Back
The person details link /persons/
and the back link /persons
are both now much cleaner in my opinion compared to the hashbang URLs.
Have a look at the complete example on Github and start the Express
app with node app.js
.
You can find the complete example on github.
If we weren’t to redirect all requests to the root, what would happen if we were to navigate to the persons list at http://localhost:3000/persons
? The Express
framework would show us an error because there is no route defined for persons
, we only defined routes for our root URL (/
) and the partials URL /partials/:name
. The redirect ensures that we actually end up at our root URL, which then kicks in our Angular app. When the client-side routing takes over we then redirect back to the /persons
URL.
Also note how navigating to a person’s detail page will load only the show.jade
partial and navigating back to the persons
list won’t carry out any server requests. Everything our app needs is loaded once from the server and cached client-side.
If you have a hard time understanding the server implementation, I suggest you read the excellent Express Guide. Additionally, there is going to be an extra chapter, which goes into more details on how to integrate Angular.js with server-side frameworks.