One of the cool things I recently started learning was AngularJS. It is a JavaScript framework for building client side JavaScript applications which follows the Model-View-Controller pattern and ensures that your application is property architectured, easy to maintain and test. Some of the great features that it offers include two way data binding, client side templates, directives, routing, promises, dependency injection, etc. All these features help to reduce the complexity of the web application. If you have previous experience using Jquery, you will immediately notice how you can manipulate the DOM easily without writing any JavaScript code.
In this tutorial, we will start by developing a simple application using Angular which will highlight some of the key features of the framework.
You can create an Angular application by simply using a text editor and downloading Angular from the official site. However, in this example, I will be using Visual Studio for the same. But it is not a necessity, you can simply use any text editor that you like.
Open Visual Studio 2013 and create a new ASP.NET application. From the templates, select the “Empty” option.
We will use Nuget to add AngularJS into our project. Right click the solution and select “Manage Nuget packages”. Search for “AngularJS” and from the result, select the AngularJS Core as shown below.
Add a new Html page to your project and call it Index.html. There are two basic requirements for using Angular in your application.
1) Add the following to your HTML page:
<script src="scripts/angular.js"></script>
This is the only file that you need to get all the core Angular features.
2) The “ng-app
” directive.
Directives are one of the core components of Angular and they are used to extend the capabilities of HTML. The “ng-app
” is the application directive and it is a special directive that Angular looks for in the application. If it finds it, Angular will initialize itself and start managing the page. Angular will only take care of the DOM sections where the directive is applied. We will add it to the <html>
element so that it applies to the whole page:
<html ng-app>
Let's add a simple binding expression to check whether Angular is working properly. Our HTML will look as shown below:
<html ng-app>
<head>
<script src="scripts/angular.js"></script>
<title></title>
</head>
<body>
<h3>Hi Angular</h3>
The result of 10 + 2 is {{ 10 + 2}}
</body>
</html>
The {{ 10 + 2 }}
that we use is a Binding expression. Angular looks for these in our pages and evaluates the expression inside them. On running the page, you will see the following output:
If you remove the ng-app attribute, Angular will not work and it will behave like a normal page.
Data Binding
To demonstrate simple data binding, let's add a simple input
tag to our page as shown below:
<div>
<input type="text" placeholder="Enter Name" ng-model="name" />
{{name}}
</div>
The ng-model=”name”
directive creates a two way data binding between the value of the textbox
and the “name
” model variable within the scope of the application. Run the application and as you type something into the textbox
, it will be immediately displayed in the page, thanks to data binding.
Now that we have some basic directives and data binding, let's create something more meaningful. We will create a simple application that will display the List of books user has read or is yet to read.
Add a new JavaScript file to the application and call it “controller.js”. Also add “Bootstrap” to the project via nuget.
Here is how our index.html code will look like:
<html ng-app>
<head>
<script src="scripts/angular.js"></script>
<script src="scripts/controller.js"></script>
<link href="Content/bootstrap.css" rel="stylesheet" />
<title></title>
</head>
<body>
<div ng-controller="MainController">
<div>
<h1>{{readingList.Name}}'s Reading List</h1>
</div>
<br />
<div>
<table class="table table-bordered table-condensed" >
<thead>
<tr>
<th>Title</th>
<th>IsComplete</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="book in readingList.Books">
<td>{{book.Title}}</td>
<td>{{book.isComplete}}</td>
<td><input type="checkbox"
ng-model="book.isComplete" /></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
In our <div>
, we use the ng-controller
directive to specify a controller. The controller controls the information that is displayed in a page. Controllers are functions that Angular invokes. The ng-controller=”MainController”
tells Angular to look for a MainController
function that will manage the contents of the div
. We can have multiple controllers inside our app and we can also nest controllers inside one another.
We define our MainController
function inside the Controller.js file. The code will look as shown below:
var MainController = function ($scope) {
var model = {
Name: "Madhur Kapoor",
Books: [{ Title: "The Hunger Games", isComplete: false },
{ Title: "The Alchemist", isComplete: true },
{ Title: "Angel & Demons", isComplete: false },
{ Title: "Da Vinci Code", isComplete: true },
{ Title: "The Godfather", isComplete: false }
]
};
$scope.readingList = model;
};
The name of the function should be the same as that defined in the ng-controller
attribute. That is how Angular identifies which function to associate with the directive. In the function, we are defining a model that contains the name along with a list of books. Our controller function takes an argument “$scope
” which is quite important. The “$
” sign specifies that it is actually an Angular component. The “$scope
” is what will act a glue between our view and the model. We can attach our model to the “$scope
” and it will be available within the scope of the controller inside the view. All the functions and variables inside the controller will be included within the $scope
.
The following code “{{readingList.Name}}’s Reading List
” reads the Name
property from the model and displays it using a binding expression.
In the below code:
<tr ng-repeat="book in readingList.Books">
<td>{{book.Title}}</td>
<td>{{book.isComplete}}</td>
<td><input type="checkbox"
ng-model="book.isComplete" /></td>
</tr>
we use the “ng-repeat
” directive which instructs Angular to repeat the <tr>
for each book
in the Books
model. In the table, I have also used a checkbox
whose model property is set to “book.isComplete
”. Run the app and you will the see the output as shown below:
You can check/uncheck the checkbox
and see how the value of isComplete
changes dynamically thanks to two way data binding.
We can also change the way the data is displayed on the page using “Filters
”. To demonstrate, we will add a new Textbox
to the page:
<input type="text" ng-model="titleFilter" placeholder="Enter Title to filter" />
We will modify the “ng-repeat
” as shown below:
<tr ng-repeat="book in readingList.Books | filter:titleFilter">
This will tell Angular to apply a filter to the list which will be driven by what is typed in our textbox
. Filters are added using the pipe “|
” symbol. We can also make the title uppercase using a filter “{{book.Title | uppercase}}
” filter. There are different types of filters available and you can also create your own filter. Run the application and as you type in the textbox
, the result of the list will be filtered.
We can also attach functions to our buttons and other elements using the “ng-click
” directive. We will add a textbox
and a button
to enable the user to add a book:
<div>
<input type="text" ng-model="newTitle"
placeholder="Enter Title To Add" required >
<input type="button" ng-click="addBook()"
value="Add" class="btn" />
</div>
Using the “ng-click
” directive, we are binding the click event to call the “addBook()
” function defined in the controller as shown below.
$scope.addBook = function () {
model.Books.push({ Title: $scope.newTitle, isComplete: false });
$scope.newTitle = '';
};
You can see that we can get the value of the textbox
using the “$scope.newTitle
” as the model is part of the scope.
Run the application, type some title in the Textbox
and click “Add”. The title that you added will be immediately added to the list.
I think this example gives you a fair idea of what can be done using Angular. In my next post, I will discuss and demonstrate some more features.