Angular JS for Web Application Development
Introduction:
AngularJS (commonly referred to as “Angular” or “Angular.js”) is a complete JavaScript-based open-source front-end web application framework mainly maintained by Google and by a community of individuals and corporations to address many of the challenges encountered in developing single-page applications. The JavaScript components complement PhoneGap, the framework used for devseloping cross-platform mobile apps. It aims to simplify both the development and the testing of such applications by providing a framework for client-side model–view–controller (MVC) and model–view–viewmodel (MVVM) architectures, along with components commonly used in rich Internet applications.
Why Angular JS?
HTML is great for declaring static documents, but it falters when we try to use it for declaring dynamic views in web-applications. AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop.
The AngularJS framework works by first reading the HTML page, which has embedded into it additional custom tag attributes. Angular interprets those attributes as directives to bind input or output parts of the page to a model that is represented by standard JavaScript variables. The values of those JavaScript variables can be manually set within the code, or retrieved from static or dynamic JSON resources.
What is Angular JS?
AngularJS is built on the belief that declarative programming should be used to create user interfaces and connect software components, while imperative programming is better suited to defining an application’s business logic. The framework adapts and extends traditional HTML to present dynamic content through two-way data-binding that allows for the automatic synchronization of models and views. As a result, AngularJS de-emphasizes explicit DOM manipulation with the goal of improving testability and performance.
AngularJS’s design goals include:
- to decouple DOM manipulation from application logic. The difficulty of this is dramatically affected by the way the code is structured.
- to decouple the client side of an application from the server side. This allows development work to progress in parallel, and allows for reuse of both sides.
- to provide structure for the journey of building an application: from designing the UI, through writing the business logic, to testing.
Angular implements the MVC pattern to separate presentation, data, and logic components. Using dependency injection, Angular brings traditionally server-side services, such as view-dependent controllers, to client-side web applications. Consequently, much of the burden on the server can be reduced.
Scope
Angular uses the term “scope” in a manner akin to the fundamentals of computer science.
Scope in computer science describes when in the program a particular binding is valid. The ECMA-262 specification defines scope as: a lexical environment in which a Function object is executed in client-side web scripts; akin to how scope is defined in lambda calculus.
As a part of the “MVC” architecture, the scope forms the “Model”, and all variables defined in the scope can be accessed by the “View” as well as the “Controller”. The scope behaves as a glue and binds the “View” and the “Controller”.
In Angular, “scope” is a certain kind of object that itself can be in scope or out of scope in any given part of the program, following the usual rules of variable scope in JavaScript like any other object. When the term “scope” is used below, it refers to the Angular scope object and not the scope of a name binding.
Bootstrap
The tasks performed by the AngularJS bootstrapper occur in three phases after the DOM has been loaded:
- Creation of a new Injector
- Compilation of the directives that decorate the DOM
- Linking of all directives to scope
AngularJS directives allow the developer to specify custom and reusable HTML-like elements and attributes that define data bindings and the behavior of presentation components. Some of the most commonly used directives are:
ng-app
Declares the root element of an AngularJS application, under which directives can be used to declare bindings and define behavior.
ng-bind
Sets the text of a DOM element to the value of an expression. For example, <span ng-bind=”name”></span> displays the value of ‘name’ inside the span element. Any change to the variable ‘name’ in the application’s scope reflect instantly in the DOM.
ng-model
Similar to ng-bind, but establishes a two-way data binding between the view and the scope.
ng-model-options
Provides tuning for how model updates are done.
ng-class
Lets class attributes be dynamically loaded.
ng-controller
Specifies a JavaScript controller class that evaluates HTML expressions.
ng-repeat
Instantiate an element once per item from a collection.
ng-show & ng-hide
Conditionally show or hide an element, depending on the value of a boolean expression. Show and hide is achieved by setting the CSS display style.
ng-switch
Conditionally instantiate one template from a set of choices, depending on the value of a selection expression.
ng-view
The base directive responsible for handling routes that resolve JSON before rendering templates driven by specified controllers.
ng-if
Basic if statement directive that allow to show the following element if the conditions are true. When the condition is false, the element is removed from the DOM. When true, a clone of the compiled element is re-inserted
ng-aria
A module for accessibility support of common ARIA attributes.
ng-animate
A module provides support for JavaScript, CSS3 transition and CSS3 keyframe animation hooks within existing core and custom directives.
Since ng-* attributes are not valid in HTML specifications, data-ng-* can also be used as a prefix. For example, both ng-app and data-ng-app are valid in AngularJS.
Two-way data binding
AngularJS’ two-way data binding is its most notable feature, largely relieving the server backend of templating responsibilities. Instead, templates are rendered in plain HTML according to data contained in a scope defined in the model. The $scope service in Angular detects changes to the model section and modifies HTML expressions in the view via a controller. Likewise, any alterations to the view are reflected in the model. This circumvents the need to actively manipulate the DOM and encourages bootstrapping and rapid prototyping of web applications. AngularJS detects changes in models by comparing the current values with values stored earlier in a process of dirty-checking, unlike Ember.js and Backbone.js that trigger listeners when the model values are changed
Alternatives
Other frameworks deal with HTML’s shortcomings by either abstracting away HTML, CSS, and/or JavaScript or by providing an imperative way for manipulating the DOM. Neither of these address the root problem that HTML was not designed for dynamic views.
Extensibility
AngularJS is a toolset for building the framework most suited to your application development. It is fully extensible and works well with other libraries. Every feature can be modified or replaced to suit your unique development workflow and feature needs. Read on to find out how.
Sample Program:
- <!doctype html>
- <html
ng-app
> - <head>
- <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/
angular.min.js
“></script> - </head>
- <body>
- <div>
- <label>Name:</label>
- <input type=“text”
ng-model
=“yourName” placeholder=“Enter a name here”> - <hr>
- <h1>Hello
{{yourName}}
!</h1> - </div>
- </body>
- </html>
Add Some Control
Data Binding
Data-binding is an automatic way of updating the view whenever the model changes, as well as updating the model whenever the view changes. This is awesome because it eliminates DOM manipulation from the list of things you have to worry about.
Controller
Controllers are the behavior behind the DOM elements. AngularJS lets you express the behavior in a clean readable form without the usual boilerplate of updating the DOM, registering callbacks or watching model changes.
Plain JavaScript
Unlike other frameworks, there is no need to inherit from proprietary types in order to wrap the model in accessors methods. Angular models are plain old JavaScript objects. This makes your code easy to test, maintain, reuse, and again free from boilerplate.
Example:
index.html
- <!doctype html>
- <html
ng-app
=“todoApp”> - <head>
- <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/
angular.min.js
“></script> - <script src=“
todo.js
“></script> - <link rel=“stylesheet” href=“todo.css”>
- </head>
- <body>
- <h2>Todo</h2>
- <div
ng-controller
=“TodoListController as todoList”> - <span>{{todoList.remaining()}} of {{todoList.todos.length}} remaining</span>
- [ <a href=“”
ng-click
=“todoList.archive()”>archive</a> ] - <ul class=“unstyled”>
- <li
ng-repeat
=“todo in todoList.todos”> - <label class=“checkbox”>
- <input type=“checkbox”
ng-model
=“todo.done”> - <span class=“done-
{{todo.done}}
“>{{todo.text}}</span> - </label>
- </li>
- </ul>
- <form
ng-submit
=“todoList.addTodo()”> - <input type=“text” ng-model=“todoList.todoText” size=“30”
- placeholder=“add new todo here”>
- <input class=“btn-primary” type=“submit” value=“add”>
- </form>
- </div>
- </body>
- </html>
todo.js
- angular.module(‘todoApp’, [])
- .controller(‘
TodoListController
‘, function() { - var todoList = this;
- todoList.
todos
= [ - {text:‘learn angular’, done:true},
- {text:‘build an angular app’, done:false}];
- todoList.
addTodo
= function() { - todoList.todos.
push
({text:todoList.todoText, done:false}); - todoList.todoText =
''
; - };
- todoList.
remaining
= function() { - var count = 0;
- angular.forEach(todoList.todos, function(todo) {
- count += todo.done ? 0 : 1;
- });
- return count;
- };
- todoList.archive = function() {
- var oldTodos = todoList.todos;
- todoList.todos = [];
- angular.forEach(oldTodos, function(todo) {
- if (!todo.done) todoList.todos.push(todo);
- });
- };
- });
todo.css
.done-true
{- text–decoration: line–through;
- color: grey;
- }
Wire up a Backend
Deep Linking:
A deep link reflects where the user is in the app, this is useful so users can bookmark and email links to locations within apps. Round trip apps get this automatically, but AJAX apps by their nature do not. AngularJS combines the benefits of deep link with desktop app-like behavior.
Form Validation:
Client-side form validation is an important part of great user experience. AngularJS lets you declare the validation rules of the form without having to write JavaScript code. Write less code, go have beer sooner.
Server Communication:
AngularJS provides built-in services on top of XHR as well as various other backends using third party libraries. Promises further simplify your code by handling asynchronous return of data. In this example, we use the AngularFire library to wire up a Firebase backend to a simple Angular app.
Example2:
index.html
- <!doctype html>
- <html
ng-app
=“project
“> - <head>
- <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/
angular.min.js
“></script> - <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/
angular-resource.min.js
“> - </script>
- <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/
angular-route.min.js
“> - </script>
- <script src=“https://cdn.firebase.com/js/client/2.0.4/
firebase.js
“></script> - <script src=“https://cdn.firebase.com/libs/angularfire/0.9.0/
angularfire.min.js
“></script> - <script src=“
project.js
“></script> - </head>
- <body>
- <h2>JavaScript Projects</h2>
- <div
ng-view
></div> - </body>
- </html>
project.js
- angular.module(‘
project
‘, [‘ngRoute’, ‘firebase
‘]) - .
value
(‘fbURL
‘, ‘https://ng-projects-list.firebaseio.com/’) - .service(‘fbRef’, function(fbURL) {
- return new Firebase(fbURL)
- })
- .service(‘fbAuth’, function($q,
$firebase
, $firebaseAuth, fbRef) { - var auth;
- return function () {
- if (auth) return $q.when(auth);
- var authObj = $firebaseAuth(fbRef);
- if (authObj.$getAuth()) {
- return $q.when(auth = authObj.$getAuth());
- }
- var deferred = $q.defer();
- authObj.$authAnonymously().then(function(authData) {
- auth = authData;
- deferred.resolve(authData);
- });
- return deferred.promise;
- }
- })
- .service(‘
Projects
‘, function($q, $firebase, fbRef, fbAuth, projectListValue) { - var self = this;
- this.fetch = function () {
- if (this.projects) return $q.when(this.projects);
- return fbAuth().then(function(auth) {
- var deferred = $q.defer();
- var ref = fbRef.child(‘projects-fresh/’ + auth.auth.uid);
- var $projects = $firebase(ref);
- ref.on(‘value’, function(snapshot) {
- if (snapshot.val() ===
null
) { - $projects.$set(projectListValue);
- }
- self.projects = $projects.
$asArray
(); - deferred.resolve(self.projects);
- });
- //Remove projects list when no longer needed.
- ref.onDisconnect().remove();
- return deferred.promise;
- });
- };
- })
- .
config
(function($routeProvider) { - var resolveProjects = {
- projects: function (Projects) {
- return Projects.fetch();
- }
- };
- $routeProvider
- .when(
'/'
, { -
controller
:‘ProjectListController as projectList’, - templateUrl:‘list.html’,
- resolve: resolveProjects
- })
- .when(‘
/edit/:projectId
‘, { - controller:‘EditProjectController as editProject’,
- templateUrl:‘detail.html’,
- resolve: resolveProjects
- })
- .when(‘/new’, {
- controller:‘NewProjectController as editProject’,
- templateUrl:‘detail.html’,
- resolve: resolveProjects
- })
- .
otherwise
({ - redirectTo:‘/’
- });
- })
- .controller(‘ProjectListController’, function(projects) {
- var projectList = this;
- projectList.projects = projects;
- })
- .controller(‘NewProjectController’, function(
$location
, projects) { - var editProject = this;
- editProject.
save
= function() { - projects.$add(editProject.project).then(function(data) {
- $location.
path
(‘/’); - });
- };
- })
- .controller(‘EditProjectController’,
- function($location,
$routeParams
, projects) { - var editProject = this;
- var
projectId
= $routeParams.projectId, - projectIndex;
- editProject.projects = projects;
- projectIndex = editProject.projects.$indexFor(projectId);
- editProject.project = editProject.projects[projectIndex];
- editProject.
destroy
= function() { - editProject.projects.$remove(editProject.project).then(function(data) {
- $location.path(‘/’);
- });
- };
- editProject.save = function() {
- editProject.projects.$save(editProject.project).then(function(data) {
- $location.path(‘/’);
- });
- };
- });
list.html
- <input type=“text”
ng-model
=“projectList.search” class=“search-query” id=“projects_search” - placeholder=“Search”>
- <table>
- <thead>
- <tr>
- <th>Project</th>
- <th>Description</th>
- <th><a href=“
#/new
“><i class=“icon-plus-sign”></i></a></th> - </tr>
- </thead>
- <tbody>
- <tr
ng-repeat
=“project in projectList.projects |filter
:projectList.search |orderBy
:’name'”> - <td><a ng-href=“{{project.site}}” target=“_blank”>{{project.name}}</a></td>
- <td>{{project.description}}</td>
- <td>
- <a ng-href=“#/edit/{{project.$id}}”><i class=“icon-pencil”></i></a>
- </td>
- </tr>
- </tbody>
- </table>
detail.html
- <form name=“
myForm
“> - <div class=“control-group”
ng-class
=“{error: myForm.name.$invalid && !myForm.name.$pristine}”> - <label>Name</label>
- <input type=“text” name=“name” ng-model=“editProject.project.name”
required
> - <span
ng-show
=“myForm.name.$error.required && !myForm.name.$pristine” class=“help-inline”> - Required {{myForm.name.$pristine}}</span>
- </div>
- <div class=“control-group” ng-class=“{error: myForm.site.$invalid && !myForm.site.$pristine}”>
- <label>Website</label>
- <input type=“
url
“ name=“site” ng-model=“editProject.project.site” required> - <span ng-show=“myForm.site.$error.required && !myForm.site.$pristine” class=“help-inline”>
- Required</span>
- <span ng-show=“myForm.site.$error.url” class=“help-inline”>
- Not a URL</span>
- </div>
- <label>Description</label>
- <textarea name=“description” ng-model=“editProject.project.description”></textarea>
- <br>
- <a href=“#/” class=“btn”>Cancel</a>
- <button ng-click=“editProject.save()”
ng-disabled
=“myForm.$invalid” - class=“btn btn-primary”>Save</button>
- <button ng-click=“editProject.destroy()”
- ng-show=“editProject.project.$id” class=“btn btn-danger”>Delete</button>
- </form>
Create Components
Directives:
Directives is a unique and powerful feature available only in Angular. Directives let you invent new HTML syntax, specific to your application.
Reusable Components:
We use directives to create reusable components. A component allows you to hide complex DOM structure, CSS, and behavior. This lets you focus either on what the application does or how the application looks separately.
Localization:
An important part of serious apps is localization. Angular’s locale aware filters and stemming directives give you building blocks to make your application available in all locales.
Example3:
index.html
- <!doctype html>
- <html ng-app=
"app"
> - <head>
- <script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js”></script>
- <script src=“components.js”></script>
- <script src=“app.js”></script>
- </head>
- <body>
- <
tabs
> - <
pane
title
=“Localization
“> - <span>Date: {{ ‘2012-04-01′ | date:’fullDate’ }}</span><br>
- <span>Currency: {{ 123456 | currency }}</span><br>
- <span>Number: {{ 98765.4321 | number }}</span><br>
- </pane>
- <pane title=“
Pluralization
“> - <div ng-controller=“
BeerCounter
“> - <div ng-repeat=“beerCount in beers”>
- <
ng-pluralize
count
=“beerCount”when
=“beerForms”></ng-pluralize> - </div>
- </div>
- </pane>
- </tabs>
- </body>
- </html>
components.js
- angular.module(‘components’, [])
- .
directive
(‘tabs
‘, function() { - return {
-
restrict
: ‘E’, -
transclude
: true, -
scope
: {}, -
controller
: function($scope
,$element
) { - var panes = $scope.panes = [];
- $scope.
select
= function(pane) { - angular.forEach(panes, function(pane) {
- pane.selected = false;
- });
- pane.selected = true;
- }
- this.
addPane
= function(pane) { - if (panes.length == 0) $scope.select(pane);
- panes.push(pane);
- }
- },
template
:- ‘<div class=”tabbable”>’ +
- ‘<ul class=”nav nav-tabs”>’ +
- ‘<li ng-repeat=”pane in panes” ng-class=”{
active
:pane.selected}”>’+ - ‘<a href=””
ng-click
=”select(pane)”>{{pane.title}}</a>’ + - ‘</li>’ +
- ‘</ul>’ +
- ‘<div class=”tab-content”
ng-transclude
></div>’ + - ‘</div>’,
-
replace
: true - };
- })
- .directive(‘pane’, function() {
- return {
require
: ‘^tabs’,- restrict: ‘E’,
- transclude: true,
- scope: { title: ‘@’ },
- link: function(scope, element, attrs,
tabsController
) { - tabsController.addPane(scope);
- },
- template:
- ‘<div class=”tab-pane” ng-class=”{active: selected}” ng-transclude>’ +
- ‘</div>’,
- replace: true
- };
- })
app.js
- angular.module(‘app’, [‘
components
‘]) - .controller(‘BeerCounter’, function($scope,
$locale
) { - $scope.
beers
= [0, 1, 2, 3, 4, 5, 6]; - if ($locale.
id
== ‘en-us’) { - $scope.
beerForms
= { - 0: ‘no beers’,
- one: ‘{} beer’,
- other: ‘{} beers’
- };
- } else {
- $scope.beerForms = {
- 0: ‘žiadne pivo’,
- one: ‘{} pivo’,
- few: ‘{} pivá’,
- other: ‘{} pív’
- };
- }
- });
Testability Built-in
Injectable:
The dependency injection in AngularJS allows you to declaratively describe how your application is wired. This means that your application needs no main()
method which is usually an unmaintainable mess. Dependency injection is also a core to AngularJS. This means that any component which does not fit your needs can easily be replaced.
Testable:
AngularJS was designed from ground up to be testable. It encourages behavior-view separation, comes pre-bundled with mocks, and takes full advantage of dependency injection. It also comes with end-to-end scenario runner which eliminates test flakiness by understanding the inner workings of AngularJS.
Every once inside a whilst we choose blogs that we study. Listed below are the most up-to-date websites that we opt for. Toney Plantier
I reckon something really interesting about your web blog so I bookmarked . Cyril Meisenheimer
Amazing! Its truly remarkable paragraph, I have got much clear idea regarding from this post. Bradley Randolph
I say Thank You because of your caring about the accuracy of your content, and thus those who read it. Dallas Curtin
There is obviously a lot to realize about this. I consider you made some nice points in features also. Quentin Fulsom
Pretty! This was a really wonderful article. Thanks for providing this information. Christopher Doino
Really enjoyed this post. Much thanks again. Much obliged. Lon Donnel
Utterly written subject matter, regards for selective information . Kurt Schoonhoven
Some genuinely fantastic articles on this web site , thanks for contribution. Darnell Varela
You are my inspiration , I own few web logs and very sporadically run out from to brand. Jim Boscarino
Pretty! This has been a really wonderful post. Thank you for providing this information. Rey Koutz
You can definitely see your skills in the work you write. Woodrow Bundi
Hi to all, how is everything, I think every one is getting more from this website, and your views are pleasant for new users. Wayne Neiswender
You are my aspiration , I have few blogs and very sporadically run out from to brand. Alfonso Hinh
Really enjoyed this blog post. Really looking forward to read more. Marcos Iacuzio
This is very interesting, You are an overly professional blogger. Wilson Herbein
Well I truly enjoyed studying it. This information provided by you is very helpful for correct planning. Faustino Stan
I really like your writing style, good information, appreciate it for putting up : D. Guy Winkels
Its fantastic as your other content :D, regards for posting. Gerard Janecka
You are my intake , I own few blogs and occasionally run out from to brand. Mac Drinen
It’s an awesome piece of writing in support of all the internet people; they will obtain benefit from
it I am sure.
There is definately a lot to find out about this topic. I like all of the points you made. Jose Cragin
Many thanks really helpful. Will certainly share site with my friends. Francis Grebs
Great, thanks for sharing this article. Much thanks again. Awesome. Sang Birkenhagen