When creating Single Page Applications with AngularJS it is quite important to handle the back button properly. The ngRoute service provides a simple way to handle this.

examples/angular/simple_router/simple_router.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport"
     content="width=device-width, initial-scale=1, user-scalable=yes">
  <title>Routing</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"></script>
<script>
angular.module("DemoApp", ['ngRoute'])
    .controller("DemoController", function($scope) {
        $scope.title = "Simple Router Example";
    })
    .config(['$routeProvider', function($routeProvider) {
        $routeProvider.
            when('/abc', {
                template: '<h2>ABC</h2> from the template',
            }).
            when('/def', {
                templateUrl: 'def.html',
            }).
            otherwise({
                redirectTo: '/'
            });
    }]);
</script>
</head>

<body ng-app="DemoApp" ng-controller="DemoController">
<h1>{{title}}</h1>
<a href="#">home</a>
<a href="#abc">abc</a>
<a href="#def">def</a>

<div ng-view></div>

</body>
</html>
Try!

We need to load both AngularJS and the Angular Route service.

In the HTML page we add an ng-view directive:

<div ng-view></div>

When we create the Angular Application using the angular.module call we need to pass 'ngRoute' in the second parameter to indicate which dependencies to use.

The controller itself can be empty. We only used it here to show where does it fit. We just fill a simple attribute that will be the h1 element in the page.

The interesting part is the config call. The $routeProvider will have a mapping of URL pathes and what to show when each one is hit.

Assuming the page lives at the URL http://example.com/example.html all the pages will be seen as anchors of that page. So for example the '/abc' route will be http://example.com/example.html#/abc

In our example if the user arrives to the /abc Angular will take the content of the template and show it in the div-element having the ng-view directive.

If the user arrives to /def, Angular will fetch the content of the 'def.html' page from the same server and will display the content of that file in the ng-view.

The otherwise entry tells the router where to redirect user arriving to any other anchoredurl. So for example example.html#/xyz will be automatically redirected to example.html#/ .

Route page with button

examples/angular/simple_router/simple_router_with_button.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport"
     content="width=device-width, initial-scale=1, user-scalable=yes">
  <title>Routing</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.min.js"></script>
<script>
angular.module("DemoApp", ['ngRoute'])
    .controller("DemoController", function($scope, $location) {
        $scope.title = "Simple Router Example";
        $scope.goto = function(page) {
            $location.path(page);
        };
    })
    .config(['$routeProvider', function($routeProvider) {
        $routeProvider.
            when('/abc', {
                template: '<h2>ABC</h2> from the template',
            }).
             when('/def', {
                templateUrl: 'def.html',
            }).
            when('/ghi', {
                templateUrl: 'ghi.html',
            }).
            otherwise({
                redirectTo: '/def'
            });
    }]);
</script>
</head>

<body ng-app="DemoApp" ng-controller="DemoController">
<h1>{{title}}</h1>
<a href="#abc">abc</a>
<a href="#def">def</a>

<button ng-click="goto('/ghi')">ghi</button>

<div ng-view></div>

</body>
</html>
Try!

In the second example there is an additional element. A button that helps us show how to change the page from within the controller. In order for this to work we had to inject the $location service into the controller.

We can then set the route but calling $location.path() and passing the new route to it. For example '/abc', or '/def' from the previous example. In our demo we have encapsulated this call in another function which we called 'goto' and which was made available in the HTML code by adding it to the $scope.

In the HTML we have a button that calls this goto function that was connected to it using the ng-click directive.

In addition, in this example we have also changed the value of the default page defined by the otherwise call. So any user arriving to a page like "#/xyz" will be redirected to "#/def"