Your First AngularJS App: Creating a View

Views are generated by combining data the controller provides with annotated HTML elements that produce content for the browser to display. In Listing 2-5, you can see how I have used one kind of annotation, known as a data binding, to populate the HTML document with the model data.

Listing2-5. Displaying the Model Data with a View in the todo.html File

<body ng-controller=”ToDoCtrl”>

<div class=”page-header”>

<h1>

{{todo.user}}’s To Do List

<span class=”label label-default”>{{todo.items.length}}</span>

</h1>

</div>

<div class=”panel”>

<div class=”input-group”>

<input class=”form-control” />

<span class=”input-group-btn”>

<button class=”btn btn-default”>Add</button>

</span>

</div>

<table class=”table table-striped”>

<thead>

<tr>

<th>Description</th>

<th>Done</th>

</tr>

</thead>

<tbody>

<tr ng-repeat=”item in todo.items”>

<td>{{item.action}}</td>

<td>{{item.done}}</td>

</tr>

</tbody>

</table>

</div>

</body>

You can see the effect of combining the model, controller, and view by using the browser to navigate to the todo.html file, as shown in Figure 2-3. I’ll explain how the HTML was generated in the sections that follow.

1. Inserting Model Values

AngularJS uses double-brace characters ({{ and }}) to denote a data binding expression. The content of the expression is evaluated as JavaScript, limited to the data and functions assigned to the scope by the controller. In this example, I can only access the parts of the model that I assigned to the $scope object when I defined the controller, using the names of the properties that I created on the $scope object.

This means, for example, that if I want to access the model.user property, I define a data binding expression that refers to todo.user; that’s because I assigned the model object to the $scope.todo property.

AngularJS compiles the HTML in the document, discovers the ng-controller attribute, and invokes the ToDoCtrl function to set the scope that will be used to create the view. As each data binding expression is encountered, AngularJS looks up the specified value on the $scope object and inserts the value into the HTML document. As an example, this expression:

{{todo.user}}’s To Do List

is processed and transformed into the following string:

Adam’s To Do List

This is known as data binding or model binding, where a value from the model is bound to the contents of an HTML element. There are a few different ways of creating data bindings, which I explain in Chapter 10.

2. Evaluating Expressions

The contents of a data binding expression can be any valid JavaScript statement, meaning that you can perform operations to create new data from the model. In Listing 2-5, I used this feature to display the number of to-do items in the list, as follows:

<div class=”page-header”>

{{todo.userjj’s To Do List<span class=”label label-default”>{{todo.items.length}}</span>

</div>

AngularJS evaluates this expression and displays the number of items in the array to tell the user how many items are in the to-do list, which I show alongside the header in the HTML document (formatted with the Bootstrap label class for formatting).

Tip You should use expressions only to perform simple operations to prepare data values for display. Don’t use data bindings to perform complex logic or to manipulate the model; that’s the job of the controller. You will often encounter logic that is hard to classify as being suitable for the view or the controller, and it can be difficult to work out what to do. My advice is to not worry about it. Make a best guess in order to preserve development momentum and move the logic later if need be. If you really can’t make a call, then put the logic in the controller; that will turn out to be the right decision about 60 percent of the time.

3. Using Directives

Expressions are also used with directives, which tell AngularJS how you want content to be processed. In the listing, I used the ng-repeat attribute, which applies a directive that tells AngularJS to generate the element it is applied to and its contents for each object in a collection, as follows:

<tr ng-repeat=”item in todo.items”>

<td>{{item.action}}</td><td>{{item.done}}</td>

</tr>

The value of the ng-repeat attribute is in the format <name> in <collection>. I have specified item in todo.items, which means the following: Generate the tr element and the td elements it contains for each of the objects in the todo.items array and assign each object in the array to a variable called item.

Using the item variable, I am able to define binding expressions for the properties of each object in the array, producing the following HTML:

 <tr ng-repeat=”item in todo.items” class=”ng-scope”>

<td class=”ng-binding”>Buy Flowers</td>

<td class=”ng-binding”>false</td>

</tr>

<tr ng-repeat=”item in todo.items” class=”ng-scope”>

<td class=”ng-binding”>Get Shoes</td>

<td class=”ng-binding”>false</td>

</tr>

<tr ng-repeat=”item in todo.items” class=”ng-scope”>

<td class=”ng-binding”>Collect Tickets</td>

<td class=”ng-binding”>true</td>

</tr>

<tr ng-repeat=”item in todo.items” class=”ng-scope”>

<td class=”ng-binding”>Call Joe</td>

<td class=”ng-binding”>false</td>

</tr>

As you’ll learn in later chapters, directives are at the core of how AngularJS works, and the ng-repeat directive is one that you will use frequently.

Source: Freeman Adam (2014), Pro AngularJS (Expert’s Voice in Web Development), Apress; 1st ed. edition.

Leave a Reply

Your email address will not be published. Required fields are marked *