OdeToCode IC Logo

Angular Abstractions: The Application

Tuesday, April 30, 2013

imageOne of the nice features of AngularJS is how the framework comes with a complete set of abstractions and features for building complex client pages from loosely structured and maintainable pieces of code. There are controllers, services, directives, data binding, and other pieces we'll continue looking at in future posts.

Angular also includes the concept of an application, which is the topic for this post.

An application is just an Angular module, which leads to a chicken and egg problem, since we haven't talked about modules, yet, but for now you can think of a module as an abstraction for packaging up related pieces of code.

For example, with Angular you can place all your controllers into a one module and all your services into a second module, or put the controllers and services all inside a single module. How many modules you define is entirely up to you and the needs of the project. Modules exist as containers that can provide configuration information, runtime dependencies, and other infrastructure support for their residents.

There are usually two features of the application module that make it "the application".

First is that the application module should know about all the other modules in the software, while those other modules might not know about each other or the application. Thus, the application module is the perfect place to bootstrap and glue together all the other components.

Secondly, the application module is the one identified by the ngApp directive. You can place this directive in the DOM using ng-app or data-ng-app attributes, as shown below in the simplest possible AnguarJS + HTML 5 page.

<!DOCTYPE html>
<html>
    <head>   
        <title>Patient Data</title>
    </head>
<body data-ng-app="PatientApp">
    <div>
        {{ patientAppVersion }}            
    </div>
    <script src="libs/angular.js"></script>
    <script src="… my scripts …"></script>    
</body>
</html>

You can have multiple applications inside a single page, but typically there will only be a single application and the ng-app directive will appear on the document's body element. After Angular loads and processes the HTML in the DOM, it will go looking for the "patientApp" module, so the following code is required:

(function () {
    "use strict";

    var app = angular.module("PatientApp", []);

    app.run(function ($rootScope) {
        $rootScope.patientAppVersion = "0.0.0.1";
    });

}());

angular.module is the API to use for creating and configuring a module. The first parameter is the name of the module, the 2nd parameter describes the other modules this module depends on (there currently are none).

The .run method will give Angular a function to execute after all the modules are loaded and the dependencies are resolved. In this sample, we'll add a property to $rootScope, which is the scope in use in the previous HTML (since we have no controllers yet). The magic of {{ data binding }} allows the web page to display the text "0.0.0.1".

You can reference the patientApp module from other JavaScript files using angular.module. The following code block could live in a separate .js file, and demonstrates how different pieces of code could be tied together to execute during the application bootstrap phase:

(function() {
    "use strict";

    var app = angular.module("PatientApp");
  
    app.run(["$rootScope", function($rootScope) {
        $rootScope.patientAppGreeting = "Hello!";
    }]);  

}());

Note: the call to angular.module does not have a 2nd parameter (the list of dependencies) in this second block. The dependencies param should only appear once for a given module. Passing the dependencies parameter again will wipe out the module definition and start over.

Also note the second code block uses a style that is safe for minification because it passes $rootScope (a well known name to Angular) in an array along with the function to invoke during the run phase. Anytime you define a function where Angular will inject dependencies you are given the option of passing the function as the last element in an array that gives Angular the well known names of the dependencies required as arguments. We'll see more examples of this style as we move forward.