Skip to content

AngularJS Templates 101

Lefteris Paraskevas edited this page Sep 25, 2013 · 15 revisions
##Overview of AngularJS ###What is AngularJS? **AngularJS** is an open-source JavaScript framework, maintained by Google, for building **Single Page Applications (SPA)** that run in a browser. Its goal is to make both development and testing of browser-based applications easier.

Basic HTML is great for displaying static documents, but is not so good at describing the dynamic views needed for interactive applications. AngularJS helps you bind data dynamically to HTML elements and even extend the HTML vocabulary with new elements and attributes that suit your application. It also encourages separation of the application logic from how the data is displayed to the user.

AngularJS is what HTML would have been, had it been designed for building web-apps.

This separation of concerns, is often called MVC (see below). It lets developers focus on building and testing the the JavaScript business logic independent of the final visualization. While the designers can create and test the the HTML/CSS views without worrying about how the business logic will be implemented.

###What is Model-View-Controller (MVC)?

MVC is not a design pattern, it is an Architectural Pattern that describes a way to structure our application and the responsibilities and interactions for each part in that structure.

The idea behind MVC is simple. We must have the following responsibilities clearly separated in our application:

####Model The Model is the data and the rules applying to that data, which represent objects that the application uses. Some of these objects hold the business data, such as User or Shopping Cart, and some objects provide services that represent the business logic, such as an Inventory or Security service. Here are some examples of Model objects for a shopping application:

  • User - containing name and address.
  • Inventory - providing getStockQuantity or findByColour
  • ShoppingCart - containing items and quantity
  • EmailNotification - containing emailAddress, subject and body
  • Security - providing login or resetPassword

In an AngularJS application the Model is represented by JavaScript objects. The data is held in properties, such as user.firstName, email.subject, order.transationDate or cart.item.quantity. The services are defined as methods, such as security.login(userName, password) or search.query(searchTerm).

The Model data objects are transmitted over the internet between the browser and the server as strings. In most web applications these strings will be either JavaScript Object Notation (JSON) - "{ userId: 123, firstName: 'Jo', lastName: 'Bloggs'}" - or, sometimes, eXtensible Markup Language (XML) - "<user user-id='123' first-name='Jo' last-name='Bloggs'></user>". JSON is preferable as it has a direct mapping to JavaScript objects.

####View The View provides different ways to present the data in the model. In an AngularJS application, views are defined as HTML and CSS. The HTML provides a template, to which AngularJS binds the data in the Model. The CSS tells the browser how to visually style the template.

There can be more than one View of a single piece of data. For example, given a model containing Stock Items in a shopping application, you could have a stock-list.html view that shows a summary of all the items in stock and and a stock-detail.html that shows the detail of a single item in the stock. Both views use data from the same model but display it in very different ways to the user.

####Controller The Controller links the view to the model. Its main function is to expose the Model data and handler functions to the View. Usually these handlers are triggered by user interactions such as clicking on a button. A handler will normally call through to an appropriate Model function to run the actual business logic based on the events from the View.

####Scope (ViewModel) AngularJS uses an object called a Scope to expose the data and handlers to the View. The Controller will take data from the Model and attach it, as properties, to the Scope. Once on the scope, these properties are available for data binding to HTML elements in the View. The Controller also attaches the event handler functions to the Scope, so that the View can also bind events to them.

This diagram shows how the different parts of the MVC pattern fit into AngularJS.

####Further Reading For more information on MVC you can look here:

##Basic Template Concepts

###Introduction HTML has a lot of constructs for formatting the HTML for static documents in a declarative fashion. For example if you wish to display an image of a map then you simply provide an <img> tag giving it a src attribute telling the browser from where to get the image. There is no need to read in the image file and then output it pixel by pixel to the screen. Such is the power of declarative language.

But the HTML language is also limited, since it does not allow you to extend what it means to display a map in the browser. For example, before HTML5 becomes mainstream, there is no easy way to get the browser to display a dynamic image of a map that can be panned and zoomed in place on the page. Moreover, there is no way to automatically display the map of an address that may be entered by the user.

What is needed is a way to teach the browser new HTML syntax.

AngularJS allows you to achieve functionality like this by using directives and data binding. It lets us use HTML as our template language and lets us extend HTML's syntax to express our application's components. In the case of maps, we could have a new <map> element that has an address attribute, which could be bound to the value of some input box on the page.

Getting Started

Before we can use AngularJS to create an application we need to load it into the browser. We do this using a <script> element:

<script src="http://code.angularjs.org/snapshot/angular.js"></script>

This element tells the browser to download the specified source file (in this case the latest bleading edge snapshot of the AngularJS library) and run it. We normally place this <script> element in the HTML, either in the <head> element or the bottom of the <body> element. Once the script is loaded we are ready to make our app. We do this by adding directives to the HTML.

###Directives AngularJS can add functionality to the browser by defining Directives that map to HTML elements, attributes, classes and even comments. It has a built in set of directives which are useful for building web applications but can be extended such that HTML can be turned into a declarative domain specific language.

Let's take a look at some of the common directives used in AngularJS applications:

ng-app

This directive defines your application. You place it as an attribute on an HTML element. This lets AngularJS know that this element and all of its children are part of an AngularJS application. There can only be one ng-app per page. We usually place it near the root of the page, for example as <html ng-app> or <body ng-app>.

Example 01 - Introduction:
<!doctype html>
<html ng-app>
  <body>
     <p>1 + 2 = {{ 1 + 2 }}</p>
     <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
  </body>
</html>

In this example you can see that we have loaded the AngularJS file. We have applied the ng-app directive to the <html> element to make the entire HTML document become an AngularJS application.

We have also used a special AngularJS databinding syntax called interpolation. The bit of text in curly braces {{}} is recognised by AngularJS as an "expression", which will be evaluated. The result is that the browser renders 1 + 2 = 3. If we did not specify an AngularJS application with ng-app, the browser would have rendered 1 + 2 = {{ 1+2 }}. Check it out yourself.

ng-model

This directive tells AngularJS create a two-way data binding. It works together with input, select, textarea. ngModel is responsible for binding the view into the model, which other directives such as input, textarea or select require. Note: ngModel will try to bind to the property given by evaluating the expression on the current scope. If the property doesn't already exist on this scope, it will be created implicitly and added to the scope. For example:

<input type="text" ng-model="firstName">

This creates an input field to insert your name. When you type your name the value that you type is inserted to a scope variable called firstName. Since the firstName variable is now attached to the scope, you can access it from the view to display your first name.

####ng-bind Now that this variable is available in the scope, let's see how we can display it in our view. For this purpose we will use the ng-bind directive. This directive tells AngularJS to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes. For example add this after your input field:

<p ng-bind="firstName"></p>

Now you will see Angular's data binding magic in action. What you type in the input field gets attached to the scope, which then is available to us in the view using the ng-bind directive. NOTE: Typically, you don't use ngBind directly, but instead you use the double curly markup like {{ expression }} which is similar but less verbose.You will find out more about this syntax in the Interpolation section.

Example 02 - ngModel and ngBind:
<!doctype html>
<html ng-app>
  <body>
     <label>Your first name:</label>
     <input type="text" ng-model="firstName"/>
     <p>Hello <span ng-bind="firstName"></p>
     <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
  </body>
</html>
Task 02 - ngModel and ngBind:

Add an extra input field to insert your last name and a text area field to insert an interesting thing about you. Use Angular's data binding to display in the view the information that you inserted. You can find an initial gist to get you going here .

###Interpolation This is the core feature of Angular's templating capabilities – a binding, denoted by double-curlies {{ }}. The binding tells Angular that it should evaluate the expression inside the double-curlies and insert the result into the DOM in the place of the binding. Rather than a one-time insert, a binding will result in efficient continuous updates whenever the result of the expression evaluation changes. More often than not you will use the {{ }} syntax instead of the ng-bind directive.

Example 03 - Interpolation:
<!doctype html>
<html ng-app>
  <body>
     <label>Your name:</label>
     <input type="text" ng-model="name"/>
     <label>Your Capgemini username: </label>
     <input type="text" ng-model="username"/>
     <p>Hello {{name}} ( {{username}} )</p>
     <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
  </body>
</html>

As expected, once this template is processed by Angular, the html page contains the text: "Hello Your_Name (Your_Username)".
Double-curlie bindings are not only used as the text of html elements. They can be used in html attributes and classes as well.

Task 03 - Interpolation:

Extend Example 03 by adding a text element to display your Capgemini email (based on your first and last names) and a link that once clicked will try to send you an email. You can find an initial gist to get you going here .
Note: You should only have two input fields (first name, last name).

###Basic Expressions Angular bindings can also contain Angular expressions. This means that you can put more complex expressions than simple variables in them. An Angular expression is a JavaScript-like code snippet that is evaluated by Angular in the context of the current model scope, rather than within the scope of the global context (window).Angular expressions are like javascript in the view. You can use common Javascript operators and variables to create your own expressions. For details on Javascript operators look here

Example 04 - Basic Expressions:
<!doctype html>
<html ng-app>
  <body>
     <label>Your name:</label>
     <input type="text" ng-model="name"/>
     <label>Your place of birth: </label>
     <input type="text" ng-model="place"/>
     <p>{{name + ' comes from ' + place}}</p>
     <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
  </body>
</html>
Task 04 - Basic Expressions:

Create a very simple exchange rate app that converts pounds to euros or dollars. You should allow the user to select between dollars and euros. You should also have an input field where the user will insert the amount of pounds they want to convert. You can find an initial gist to get you going here .

###Filters

Angular filters format data for display to the user. They are special javascript functions that modify the output of the string.
For more information on javascript functions you can look here
In order to apply a filter to a binding use the following syntax:

{{ variable | filter }}

Look at the following examples that make use of some of Angular's built in filters.

Example 05 - Filters:
<!doctype html>
<html ng-app>
  <body>
    <div>
      <label>Select date: </label>
      <input type="date" ng-model="myDate"/>
      {{ myDate | date:'EEEE, MMMM d,y' }}  
    </div>
    <div>
      <p>This text will always be in upper case</p>
      <label>Insert text: </label>
      <input type="text" ng-model="myText"/>
      {{ myText | uppercase }}  
    </div>
     <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
  </body>
</html>

In this example we insert a date. Then we use the date built-in angular filter to format the date. You can change the format of the date by changing the filter. Also we make use of the uppercase filter. This simply converts any text to upper case.
Task 05 - Filters:

Create a simple app that will calculate the percentage. It will have two input fields (numerator, denominator). The percentage that you calculate should have two decimal points.
NOTE: Look at angular's number built-in filter. Also do not forget the power of angular expressions!

###Controllers Provide new behaviour and initialisation for the scope AngularJS Modules and ng-app="userApp" Explain that controllers exist inside modules and you have to tell AngularJS what module to load ng-controller="UserController" Initializing Scope Explain that the scope will be initialised with a user object user = { dob: ... } Using Functions Age : {{ getAge(user.dob) }} years Gravatar: ###Working with Lists ng-repeat ng-repeat="team in teams" child scopes $index, $first, $last, $even, $odd filtering and ordering team in teams | filter : search | orderBy : 'points'

...
exercise ###Using Custom Directives Created by JS programmers. Internally by CapGemini or 3rd party ###Including Partials Hosting in a server grunt server ng-include ###Other directives ng-show/ng-hide show or hide a description of user exercise ng-class syntax ng-class="{ cssClassName : showClass }", "cssClassName" ###Form Validation required, ng-pattern, etc CSS classes ng-valid, ng-invalid, ng-dirty, ng-pristine red borders, etc exercise {{ myForm.someInput.$valid}} etc use ng-show etc. exercise use ng-class to for Foundation classes exercise