Angular Views and Routing

Angular Views and Routing

Often, a website's functionality cannot be limited to a single page. For example, when going through the checkout process on an e-commerce site, you may go through many different views to submit and verify information. Traditionally, each new view would require a new page load from the server, which is unpleasant for the user and difficult to manage for the developer. Fortunately, Angular solves this problem by facilitating view-switching without leaving the page. This is ideal for working with RESTful APIs, and the user experience is much faster as well.

Routes

Each view of the app is defined as a route, a controller, and a template. The site root is /, and you can define any type of routes you want, like /turkey or /banana/pudding (It even supports route parameters like /user/:id). The controller is just a normal angular controller. And the template is just the HTML that goes along with the controller. Here is an example of a single route:

// home.js
angular.module('myApp', ['ngRoute'])

.config(function ($routeProvider) {
  $routeProvider.when('/home', {
    controller: 'homeController',
    templateUrl: 'home.html'
  });
})

.controller('homeController', function ($scope) {
  $scope.name = 'The Postal Service';
});

$routeProvider comes from the ngRoute module which you will include in index.html (you'll see that soon). controller just references the controller we define in the file. templateUrl references a separate file entirely. Here is the HTML file:

// home.html
<h4>Welcome to the home page of {{ name }}</h4>

{{ name }} references the scope variable defined in homeController.

We also have an index.html file:

// index.html
<!doctype html>

<html ng-app="myApp">
<head>
  <title>My App</title>
</head>

<body>
  <div>
    (This part can be seen in every view)
    <a href="/#/home">Home page</a>
  </div>

  <ng-view></ng-view>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-route.js"></script>
  <script src="components/app.js"></script>
  <script src="components/home.js"></script>
</body>
</html>

This is where we include angular, ngRoute, and our other js files. The most interesting portion of this file is the <ng-view> tag. When you visit /home the template HTML is automatically inserted into the <ng-view> tag, and the corresponding controller is linked to the <ng-view> tag as well.

When we fire up our index file from a server, (using live preview in Brackets works great!) we should see this:

And when we click on the link, we should see this:

When you visit the /#/home route, it shows the template and controller you defined with $routeProvider:

The # is how angular distinguishes front-end routes from server routes. It is possible to remove it with the correct server configuration

Multiple Routes

We can continue to configure routes in the same files as our controllers, but for this class we will do that all in app.js. It's a simpler separation of concerns for us.

We will also abstract our different views into a components folder, and each view will have it's own folder. Like so:

app.js and index.html are directly in the routing folder. They are siblings to the components folder.

The about folder will have an about.js and an about.html. Same pattern for the home folder.

Now let's add another view. Here are the files for an about page:

// about.js
angular.module("myApp")

.controller("AboutController", ["$scope", function($scope) {
    
    $scope.name = "Bartholomew";
    
}]);

// about.html
<h1>About page</h1>
<h3>{{ name }}</h3>
<img src="http://www.placekitten.com/g/300/400" alt="Even more kittens!">

Make sure to include about.js in a script tag in index.html. I'll also add a link to /#/about in index.html. Here is what the about page looks like. (The views can be switched with the links, which go to their respective routes.)

Now in our app.js we can configure our routes.

// app.js
angular.module("myApp", ["ngRoute"])

.config(["$routeProvider", function($routeProvider) {
    
    $routeProvider
        .when("/home", {
            templateUrl: "components/home/home.html",
            controller: "HomeController"
        })
        .when("/about", {
            templateUrl: "components/about/about.html",
            controller: "AboutController"
        })

}]);

One more thing ... This is how you define a default route:

// app.js
angular.module("routingApp", ["ngRoute"])

.config(["$routeProvider", function($routeProvider) {
    
    $routeProvider
        .when("/home", {
            templateUrl: "components/home/home.html",
            controller: "HomeController"
        })
        .when("/about", {
            templateUrl: "components/about/about.html",
            controller: "AboutController"
        })
        .otherwise({
            redirectTo: "/home"
        });
}]);

The otherwise function sets a route to fallback on if the route that the user enters is not registered. (So if you go to / in the browser, it will redirect to /#/home.)

This tutorial was written for angular-route 1.5.6 and angular 1.5.6.