The first question that comes to mind is why do we need a front-end framework like Angular.JS? jQuery has been a blessing to the front-end world with its rich features to manipulate the DOM (Document Object Model). Where it falls flat is the inability to organize the front-end logic into the different concerns viz. model, view and controller. This is where Angular shines and we will take an in depth look at it.
I will be using the example of a shopping cart for this blog. Let us assume that the product list is available as a JSON API call. For starters let me show you how does to get a simple shopping cart created using Angular. Let us get started.
View
<!DOCTYPE html>
<html ng-app="ShoppingApp">
<head lang="en">
<name>My Shopping Cart</name>
<meta charset="UTF-8">
<script src="javascripts/angular.min.js"></script>
<script src="javascripts/controllers.js"></script>
</head>
<body ng-controller="ShoppingController">
<h1>Shop!</h1>
<table>
<tr ng-repeat="item in items">
<td>{{item.name}}</td>
<td>{{item.artist}}</td>
<td>{{item.description}}</td>
<td>{{item.price | currency}}</td>
<td><button ng-click="remove($index)">Remove</button></td>
</tr>
</table>
</body>
</html>
ng-app is an Angular Directive. It tells Angular which is the root element for the application and it takes full control of the all the elements inside this element. ng-controller directive attaches a controller class to the view.
Download the latest version of angular and save it under a directory called javascripts. Alternatively, you can use the CDN version of the latest angular version and use that. Now that we got that out of the way, we need to define our controller.
Whatever!
'use strict';
(function () {
var shoppingModule = angular.module('ShoppingApp', []);
shoppingModule.controller('ShoppingController', ['$scope', '$http', function($scope, $http) {
$http.get('/products/products.json').success(function(data, status, headers, config) {
$scope.items = data;
});
$scope.remove = function(index) {
$scope.items.splice(index, 1)
}
}]);
})();
There are several design patters - Model/View/Controller, Model2, Model/View/Adapter, Model/View/ViewModel. This topic is out of scope for this blog so we are going to just leave it as Model/View/Whatever for now.
// I am going to assume that you've been able to setup a simple webservice that returns JSON data like so
[
{
"id": 0,
"name": "Wish you were here",
"artist": "Pink Floyd",
"description": "Blue Ray",
"price": 19.98
},
{
"id": 2,
"name": "Remember That Night - Live At the Royal Albert Hall",
"artist": "Dave Gilmour",
"description": "DVD",
"price": 22.99
},
{
"id": 2,
"name": "Pulse",
"artist": "Pink Floyd",
"description": "Blue Ray",
"price": 14.99
}
]
First, we create an Angular module refering to the name we gave in ng-ap directive in the HTML. Once created we can create multiple controllers attached to this module. In the above exmaple we are defining a controller called ShoppingController. We are injecting $scope and $http - we will look at dependency injection a little later. Next we are making the API call to get the products and store it in $scope, which is essentially setting the model.
Model
$scope is an object that refers to the application model. It is the glue between the application controller and the view.
Data Binding
With Angular we can establish a 2-way binding between the model and the view. This can be demostrated with a simple example.
<!DOCTYPE html>
<html ng-app="BindingApp">
<head lang="en">
<title></title>
<meta charset="UTF-8">
<script src="javascripts/angular.min.js"></script>
<script src="javascripts/controllers.js"></script>
</head>
<body ng-controller="BindingController">
<input ng-model='greeting.text'>
<p>{{greeting.text}}, World!</p>
</form>
</body>
</html
'use strict';
(function () {
var app = angular.module('BindingApp', []);
app.controller('BindingController', ['$scope', function ($scope) {
$scope.greeting = { text: 'Hello' }
}]);
})();
Observe how the view element - text input box in this case is bound to the model and changing one reflects on the other instantaneously.
Dependency Injection
Dependency Injection (DI) is a software design pattern that deals with how components get hold of dependencies. Components such as services, directives, filters, and animations are defined by an injectable factory method or constructor function. These components can be injected with "service" and "value" components as dependencies.
Let us see an example of DI in action
app.controller('SomeController',
['$scope', '$routeParams', 'Messages', function($scope, $routeParams, Messages) {
$scope.message = Messages.query()[$routeParams.id];
}]);
In the above example we are injecting $scope, $routeParams and customer module Messages into our controller.
Directives
Directives extend the HTML syntax and are the way to associate behavior and DOM transformations with custom elements and attributes. Through them, you can create resuable UI components. You'll know it's time to break into directives when you deal with browser events or mofify DOM in a way that isn't already supported by built-in directives.
Let's see an example of directives in action. Let's say you have a chunk of your template that represents a customer's information. This template is repeated many times in your code. When you change it in one place, you have to change it in several others. This is a good opportunity to use a directive to simplify your template. Let's create a directive that simply replaces its contents with a static template
<div ng-controller="Controller">
<div my-customer></div>
</div>
angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.customer = {
name: 'Naomi',
address: '1600 Amphitheatre'
};
}])
.directive('myCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
1.3 Vs 2.0!
Based on initial reports there will be several changes in Angular 2.0 but some of it is necessary since it includes new technologies like EC6 (ECMAScript 6), Web Components and more. There are rumors that 2-way binding maybe go in 2.0, we'll have to see about that. The important question that comes to mind is how do you build keeping Angular 2.0 in mind. Well, you can't. The purpose of 2.0 in my mind is to make the syntax cleaner and if there are breaking changes, so be it. I have personally dealt with a lot of it with Rails - and so far i can say that it was for the better. Only time will tell.
Conclusion
Angular.JS provides a way to organize the front-end logic into smaller pieces. It is very easy to learn and it has a ton of features. Nobody knows what the future has in store for Angular, but i trust the leadership of Angular to come up with the right decisions.}})