AngularJS Modules and Controllers
Defining Modules and Controllers
The previous examples used AngularJS, but they did not contain any JavaScript scripts. When you want to implement real processing, how you combine scripts becomes important.
Modules
AngularJS combines scripts using something called a module. A module is like a collection of programs used in AngularJS. AngularJS programs are combined in module units. A module can contain several small programs.
AngularJS lets you assign AngularJS features to a tag by specifying the ng-app attribute. With ng-app, you can specify a module name. For example:
<body ng-app="hoge">
This lets the <body> tag use the features of the hoge module.
Controllers
A module is a collection of programs, but it does not directly include processing by itself. Usually, you create something called a controller in this module.
A controller is an object that organizes various operations and values. Creating methods and properties in this controller is essentially “writing an AngularJS program.” You can store as many controllers as needed in a module.
Controllers are used by writing a controller specification on a tag, just like modules. This uses the ng-controller attribute.
<○○ ng-controller="controller name">
This lets you use the specified controller inside the <○○> tag. A module can contain multiple controllers, so you can change the scope of use as needed, such as “controller A is used in this part.” Of course, multiple controllers can also be used at the same time.
Understanding what modules and controllers are is the first step in AngularJS development.
Creating and Using Modules and Controllers
This section explains how to create and use a simple example with modules and controllers.
First, create an HTML file. A simple example is shown below.
<!DOCTYPE html>
<html>
<head>
<title>AngularJS Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
<style>
body { color:gray; }
h1 { font-size:18pt; font-weight:bold; }
span.label { display:inline-block;width:50px; color:red; }
input { width:100px; }
.msg { font-size:14pt; font-weight:bold;color:gray; }
</style>
</head>
<body ng-app="myapp" ng-init="num = 1000">
<h1>Tax Calculation</h1>
<p>Please enter an amount.</p>
<div ng-controller="HeloController as ctl">
<div class="input">
<span class="label">tax:</span>
<input type="text" ng-model="ctl.tax">%
</div>
<div class="input">
<span class="label">price:</span>
<input type="text" ng-model="num">won
</div>
<p class="msg">Including tax: {{ctl.calcWithTax(num)}}won</p>
<p class="msg">Excluding tax: {{ctl.calcWithoutTax(num)}}won</p>
</div>
</body>
</html>
Here, a script file is loaded with <script src="script.js"></script>. This script.js file is the main AngularJS program.
In general, JavaScript programs are either written directly inside HTML files or placed in separate script files and loaded. AngularJS programs can also be created either way.
However, if you care about MVC architecture and want to separate screen display from processing, writing JavaScript code directly inside HTML is not a very good method. It is more natural to separate it into another file and write the controller there, as shown here.
Using a Controller
Here, the myapp module is used as follows.
<body ng-app="myapp" ng-init="num = 1000">
This lets you use controllers in the myapp module. The controller is used as follows.
<div ng-controller="HeloController as ctl">
The myapp module has a controller named HeloController. However, this name is a little long. as can give a controller an alias. Specifying HeloController as ctl lets you use HeloController with the name ctl.
<input type="text" ng-model="ctl.tax">%
<input type="text" ng-model="num">won
The <input> tags of the input fields specify models with ng-model. num is a value initialized on the <body> tag with ng-init="num = 1000".
ctl.tax is a value in the controller. It sets the tax property inside ctl, or HeloController, as a model.
<p class="msg">Tax: {{ctl.calcWithTax(num)}}won</p>
<p class="msg">Excluding tax: {{ctl.calcWithoutTax(num)}}won</p>
These write the values of the calcWithTax and calcWithoutTax methods in HeloController. Processing, or methods, in the controller can be called in this way.
Creating the Script
Now create the script used in the example. The example code is shown below. Place it in the same location as the HTML file with the file name script.js.
angular.module('myapp',[])
.controller('HeloController',
function(){
this.tax = 8;
this.calcWithTax = function(val){
return Math.floor(val * (100 + this.tax * 1) / 100);
};
this.calcWithoutTax = function(val){
return Math.floor(val / (100 + this.tax * 1) * 100);
};
}
);
This example modifies the consumption tax calculation created earlier. It had two input fields, tax and price. When you enter the tax rate and amount, this script calculates and displays the price including tax and the price excluding tax in real time.
Creating a Module
angular.module(name, array);
Create a module using the module method of the angular object. The angular object is the basic object of AngularJS. All AngularJS features are organized in this object.
The module method specifies the module name text as the first argument. The second argument specifies an array of other modules referenced by this module. If there is nothing to reference, pass an empty array.
Although it is not used specially here, the module method returns the created module object as its return value.
Creating a Controller
module.controller(name, function);
A controller is created with the controller method of the module created by module. The first argument specifies the controller name.
The second argument is important. It contains the implementation part combined with the controller. It is written as a function, but this becomes the controller’s constructor function.
A constructor function is used in JavaScript to create objects. Define properties and methods there.
Module Form
Let us look at the example code written earlier. This sample has the following form.
angular.module('myapp',[])
.controller('HeloController',
function() {
...omitted...
}
}
);
angular.module creates the myapp module, and controller is called to define HeloController. Inside the constructor function, the tax property and the two methods calcWithTax and calcWithoutTax are provided.
This pattern, “create a module,” “create a controller,” and “implement required values and processing in the constructor function,” is the basis of using modules and controllers.
Constructor Function
How to create the constructor function prepared in a controller is the core of using AngularJS.
A constructor function creates a JavaScript object. It defines the properties and methods provided to the object.
function(){
this.○○ = ☓☓; // Define a property.
this.△△ = function(){...} // Define a method.
}
A constructor defines properties and methods, that is, variables that store values and functions that implement processing, inside itself. This is written by assigning values to properties inside this, such as this.○○.
this is the object itself created by the constructor function. In this way, you assign values to the object’s own properties and build the object contents. Constructor functions are not limited to AngularJS; they are a technique used throughout JavaScript.
Creating a Simple Database
This time, let us create an example that handles data. The controller stores data in an array, then retrieves and displays it. In short, it is an example of using a simple database.
HTML Screen Display
First, create the HTML file. The example code is shown below.
<!DOCTYPE html>
<html>
<head>
<title>AngularJS Sample</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
<style>
body { color:gray; }
h1 { font-size:18pt; font-weight:bold; }
span.label { display:inline-block;width:50px; color:red; }
input { width:100px; }
.msg { font-size:14pt; font-weight:bold;color:gray; }
</style>
</head>
<body ng-app="myapp" ng-init="num=0">
<h1>Data Display</h1>
<p>Please enter an ID number.</p>
<div ng-controller="HeloController as ctl">
<div class="input">
<span class="label">ID:</span>
<input type="text" ng-model="num">
<button ng-click="ctl.doAction(num)">click</button>
</div>
<p class="msg">{{ctl.getData()} }</p>
</div>
</body>
</html>
Here, AngularJS features are used in three places.
Setting the myapp Module
<body ng-app="myapp" ng-init="num = 0">
First, set the myapp module on <body> and initialize the variable num. This lets the <body> use the features of the myapp module.
Setting num
<input type="text" ng-model="num">
The prepared variable num is used here. Set num as the model that manages the value of the input field. This keeps the entered value stored in num.
Displaying getData Data
<p class="msg">{{ctl.getData()}}</p>
This is the part that retrieves and displays data. It calls the getData method of HeloController. This method returns the data for the currently entered number as text, so the required data is always displayed here.
Setting Click Behavior
<button ng-click="ctl.doAction(num)">click</button>
The new attribute here is ng-click. It corresponds to the onclick attribute and executes processing when clicked. The display set as {{ctl.getData()}} in <p class="msg"> updates in real time, but sometimes a “run action when clicked” approach is also needed.
Defining the Module and Controller
Write the script. The example is below. Save it as script.js.
var myapp = angular.module('myapp',[]);
myapp.controller('HeloController',
function(){
this.count = 0;
this.data = [
[0,'nobody','nodata...'],
[1,'성진','sungjin@foryou'],
[2,'원석','wonsuck@flower'],
[3,'병호','byeongho@devkuma.com']
];
this.getData = function(){
return this.data[this.count][0] + ': ' +
this.data[this.count][1] + ', ' +
this.data[this.count][2] + '.';
};
this.doAction = function(num){
this.count = num;
}
}
);
After writing it, access the page. If you enter a number from 1 to 3 in the input field, the data for that number is displayed. If you add more contents to the data property, you can handle more data.
This time, the module created with the module method is assigned to a variable, and the controller method is called from that variable. Either way of writing is fine, but when you need to specify multiple controllers in a module, it is convenient to make the module a variable like this.
Here, data is stored as an array in this.data. This is a two-dimensional array containing values such as ID number, name, and email address. The getData method retrieves the data at the index number set in the count property, converts it to text, and returns it.
How Does ng-click Execute?
This time, in addition to getData, a method named doAction was created. This method is called and processed by ng-click.
What it does is simple: it sets the argument num to the count property. When this processing changes the count value, the display where {{ctl.getData()}} is specified in the template is immediately updated and changes to the changed data.
Because the display is automatically updated by AngularJS, the action method only needs to rewrite the stored value. You can see that this feels quite different from normal JavaScript action processing.