Setup
A single page application in AngularJS makes use of the following components:
- A route provider that will listen to hash changes and will display the appropriate view.
- An html template for each route.
- A controller for each route.
- A placeholder for the views (the html templates)
- A Service to share data across controllers
HTML File
In the HTML file, we need to add a script element that will reference angular.route.js, which contains the ngRoute module (https://docs.angularjs.org/api/ngRoute). We then need to use the view directive as a placeholder for the view templates. In the following code we also have links to # and #/second; these will be the hash values that ngRoute will be monitoring.
<!DOCTYPE html> <html lang="en-us" ng-app="myApp"> <head> ... <!-- load angular via CDN --> <script src="//code.angularjs.org/1.3.0-rc.1/angular.min.js"></script> <script src="//code.angularjs.org/1.3.0-rc.1/angular-route.min.js"></script> <script src="app.js"></script> </head> <body> <header> <nav class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="/">AngularJS</a> </div> <ul class="nav navbar-nav navbar-right"> <li><a href="#"><i class="fa fa-home"></i> Home</a></li> <li><a href="#/second"><i></i> Second</a></li> </ul> </div> </nav> </header> <div class="container"> <div ng-view></div> </div> </body> </html>
JavaScript File
In the javascript file we perform 3 tasks:
- declare ngRoute as a dependency.
- call the module.config function providing a function that takes $routeProvider as an argument. We are effectively injecting $routeProvider. (Note: If we use a code minifier, the variable name will be changed. How do we deal with this?) Inside the configuration function we configure the route provider to deal with each possible route pattern. Notice that each call to ‘when’ takes a route and a configuration object that includes the template and the controller. The templates are files with html.
- We create one controller for each view. Each controller receives its own scope.
var myApp = angular.module('myApp', ['ngRoute']); myApp.config(function ($routeProvider) { $routeProvider .when('/', { templateUrl: 'pages/main.html', controller: 'mainController' }) .when('/second', { templateUrl: 'pages/second.html', controller: 'secondController' }) }); myApp.controller('mainController', ['$scope', '$log', function($scope, $log) { $scope.name = 'Main'; }]); myApp.controller('secondController', ['$scope', '$log', function($scope, $log) { $scope.name = 'Second'; }]);
Route Patterns and RouteParams
When configuring the routeProvider, values in the route path can be assigned to $routeParams by using the following notation:
- path can contain named groups starting with a colon: e.g. :name. All characters up to the next slash are matched and stored in $routeParams under the given name when the route matches.
- path can contain named groups starting with a colon and ending with a star: e.g.:name*. All characters are eagerly stored in $routeParams under the given name when the route matches.
- path can contain optional named groups with a question mark: e.g.:name?.
For example, in the following code in line 4, :num indicates that for a match to occur there would be a value after second/. That value would be assigned to a num variable in the $routeParams object. $routeParams is injected into the controller in line 14. In line 15 we access the num value and assign it to the scope.
var myApp = angular.module('myApp', ['ngRoute']); myApp.config(function ($routeProvider) { $routeProvider .when('/second/:num', { templateUrl: 'pages/second.html', controller: 'secondController' }) }); myApp.controller('mainController', ['$scope', '$log', function($scope, $log) { $scope.name = 'Main'; }]); myApp.controller('secondController', ['$scope', '$log', '$routeParams', function($scope, $log, $routeParams) { $scope.num = $routeParams.num || 1; }]);
Sharing Data Across Controllers
Controllers should share data through a custom service as explained here: http://codermem.com/javascript/angularjs/angularjs-service/