Building an Address Book App
In the earlier examples, we saw the different ways of creating models. When creating production grade or large-scale applications, which involve graphical interfaces, it is compulsory to follow the Model View Controller (MVC) design pattern.
Building on the previous code example, we'll go ahead and build a simple Address Book App.
Let's start by creating our models in a controller called PeopleController
. We'll now write all our JavaScripts in a file called scripts.js
. Your scripts.js
file should look like this:
function PeopleController($scope){ $scope.people=[ {name:"John Doe", phone: "3452345678", city:"New York"}, {name:"Sarah Parker", phone: "1236548769", city:"Chicago"}, {name:"Little John", phone: "4567853432", city:"Los Angeles"}, {name:"Adam Doe", phone: "9025673152", city:"Las Vegas"} ]; }
Here we are defining the controller called PeopleController
and creating our model called people
. The model contains three attributes: name
, phone
, and city
.
Now, let us get our markup in place. Let us call the file index.html
using the following code:
<!DOCTYPE html> <html ng-app> <head> <title>Address Book</title> </head> <body ng-controller="PeopleController"> <h1>Address Book</h1> <div> <div ng-repeat="person in people"> <div>{{person.name}} - {{person.phone}}</div> <span>{{person.city}} </span> </div> </div> <script src= "angular.min.js" type="text/javascript"></script> <script src= "scripts.js" type="text/javascript"></script> </body> </html>
Tip
It is always a good practice to load your JS files at the end of the page just above the body tag and not in the head. You can read more about why this matters here at https://developer.yahoo.com/performance/rules.html.
As you can see here, we are defining the HTML5 doctype
in the first line, and then we initialize the AngularJS application by using the ng-app
directive. You'll also notice that we are using the ng-controller
directive and assigning PeopleController
to it. By doing so, we are defining the section of the DOM that is now within the scope of this controller.
You'll also notice a new directive called ng-repeat
; this is the built-in directive used to display a list of items from a collection. The ng-repeat
directive would simply duplicate the DOM element and bind the defined properties of the data object.
As you can see, ng-repeat
makes it so easy and clean to display record sets as compared to doing this in jQuery or plain vanilla JavaScript.
Now, run your index.html
in the browser and you should be seeing the names with their phone numbers and cities being displayed. The data from our model is showing up, which is good. Let us also inspect the code to have a look at the changes AngularJS is making to our markup.
All modern browsers allow you to inspect the source. And in most cases you can simply right-click on the page and select Inspect Element. In case you are not comfortable with Inspect, you can also do View Source. Refer to the following screenshot:
Tip
By the way, here I'm using Firebug, an awesome add-on for Mozilla Firefox.
As you look through the code, you'll notice that AngularJS is making a fair bit of change to the markup.
The first thing you'll notice is that AngularJS adds a class called ng-scope
to every DOM element where the scope is initialized (we will get to what a scope is, in just a bit). It duplicates the entire DOM present within the ng-repeat
directive. It is also adding a class called ng-binding
to every element where the data is bound.
AngularJS will add different CSS classes depending on the directive being used. These can come in handy when you want to style, for example, the validation messages while working with forms. We'll see more about this in the chapters ahead.
Understanding the scope in AngularJS
Let us now look at this thing called the scope. As you might have noticed, we defined our people controller with a $scope
parameter. We also had to define our people model as a part of this scope. While inspecting the elements, we also noticed multiple ng-scope
classes being defined. So, what exactly is this scope and is it really that important?
As per AngularJS's documents, the scope object refers to the application model and provides an execution context for the expressions in the views.
The expression {{person.name}}
is able to display the content only because the name is a property that can be accessed by the scope.
Another important thing to note is that every AngularJS app will have a root scope created at the ng-app
directive. Many other directives could also create their own scope. Scopes are arranged in a hierarchical fashion following the DOM structure of the page. Child Scopes prototypically inherit from their parent scope.
The exception to this is in cases where a directive uses a scope option, it creates an isolated scope. More information about the directives and isolated scope is available in Chapter 5, Facebook Friends' Birthday Reminder App.
We'll get a better understanding of it as we see other examples.