We've seen enough examples of AngularJS templates to realize that it is not yet another templating language, but quite a different beast. Not only does the framework rely on the HTML for its template syntax and allow us to extend the HTML vocabulary, but it has the unique ability to refresh parts of the screen without any manual intervention!

In reality, AngularJS has even more intimate connections to HTML and the DOM as it depends on a browser to parse the template's text (as a browser would do with any other HTML document). After a browser is done transforming the markup's text to the DOM tree, AngularJS kicks in and traverses the parsed DOM structure. Each time it encounters a directive, AngularJS executes its logic to turn directives into dynamic parts of the screen.

Since AngularJS depends on a browser to parse templates, we need to ensure that the markup represents valid HTML. Pay special attention to close the HTML tags properly (failing to do so won't produce any error messages, but the view won't be rendered correctly). AngularJS works using the live, valid DOM tree!

AngularJS makes it possible to enrich HTML's vocabulary (we can add new attributes or HTML elements and teach a browser how to interpret them). It is almost similar to creating a new domain-specific language (DSL) on top of HTML and instructing a browser on how to make sense of the new instructions. You can often hear that AngularJS "teaches browsers new tricks".

Declarative template view â the imperative controller logic

There are many handy directives shipped with AngularJS, and we are going to cover most of the existing ones in the following chapters. What is probably more important, however, is not the syntax and functionality of individual directives but rather the underlying AngularJS philosophy of building UIs.

AngularJS promotes a declarative approach to UI construction. What it means in practice is that templates are focused on describing a desired effect rather than on ways of achieving it. It all might sound a bit confusing, so an example might come in handy here.

Let's imagine that we were asked to create a form where a user can type in a short message, and then send it by clicking on a button. There are some additional user-experience (UX) requirements such as message size should be limited to 100 characters, and the Send button should be disabled if this limit is exceeded. A user should know how many characters are left as they type. If the number of remaining characters is less than ten, the displayed number should change the display style to warn users. It should be possible to clear text of a provided message as well. A finished form looks similar to the following screenshot:

The preceding requirements are not particularly challenging and describe a fairly standard text form. Nevertheless, there are many UI elements to coordinate here such as we need to make sure that the button's disabled state is managed correctly, the number of remaining characters is accurate and displayed with an appropriate style, and so on. The very first implementation attempt looks as follows:

<div class="container" ng-controller="TextAreaWithLimitCtrl"> <div class="row"> <textarea ng-model="message">{{message}}</textarea> </div> <div class="row"> <button ng-click="send()">Send</button> <button ng-click="clear()">Clear</button> </div> </div>

Let's use the preceding code as a starting point and build on top of it. Firstly, we need to display the number of remaining characters, which is easy enough, as given in the following code:

<span>Remaining: {{remaining()}} </span>

The remaining() function is defined in the TextAreaWithLimitCtrl controller on the $scope as follows:

$scope. remaining = function () { return MAX_LEN - $scope.message.length; };

Next, we need to disable the Send button if a message doesn't comply with the required length constraints. This can be easily done with a little help from the ng-disabled directive as follows:

<button ng-disabled="!hasValidLength()" ...>Send</button>

We can see a recurring pattern here. To manipulate UI, we only need to touch a small part of a template and describe a desired outcome (display number of remaining characters, disable a button, and so on) in terms of the model's state (size of a message in this case). The interesting part here is that we don't need to keep any references to DOM elements in the JavaScript code and we are not obliged to manipulate DOM elements explicitly. Instead we can simply focus on model mutations and let AngularJS do the heavy lifting. All we need to do is to provide some hints in the form of directives.

Coming back to our example, we still need to make sure that the number of remaining characters changes style when there are only a few characters left. This is a good occasion to see one more example of the declarative UI in action, as given in the following code:

<span ng-class="{'text-warning' : shouldWarn() }"> Remaining: {{remaining()}} </span>

where the shouldWarn() method is implemented as follows:

$scope. shouldWarn = function () { return $scope.remaining() < WARN_THRESHOLD; };

The CSS class change is driven by the model mutation, but there is no explicit DOM manipulation logic anywhere in the JavaScript code! UI gets repainted based on a declaratively expressed "wish". What we are saying using the ng-class directive is this: "the text-warning CSS class should be added to the <span> element, every time a user should be warned about exceeded character limit". This is different from saying that "when a new character is entered and the number of characters exceeds the limit, I want to find a <span> element and change the text-warning CSS class of this element".

What we are discussing here might sound like a subtle difference, but in fact declarative and imperative approaches are quite opposite. The imperative style of programming focuses on describing individual steps leading to a desired outcome. With the declarative approach, focus is shifted to a desired result. The individual little steps taken to reach to this result are taken care of by a supporting framework. It is like saying "Dear AngularJS, here is how I want my UI to look when the model ends up in a certain state. Now please go and figure out when and how to repaint the UI".

The declarative style of programming is usually more expressive as it frees developers from giving very precise, low-level instructions. The resulting code is often very concise and easy to read. But for the declarative approach to work, there must be machinery that can correctly interpret higher-level orders. Our programs start to depend on these machinery decisions and we need to give up some of the low-level control. With the imperative approach, we are in full control and can fine tune each and every single operation. We've got more control, but the price to pay for "being in charge" is a lot of lower-level, repetitive code to be written.

People familiar with SQL language will find all this sounding familiar (SQL is a very expressive, declarative language for adhoc data querying). We can simply describe the desired result (data to be fetched) and let a (relational) database figure out how to go about retrieving specified data. Most of the time, this process works flawlessly and we quickly get what we have asked for. Still there are cases where it is necessary to provide additional hints (indexes, query planner hints, and so on) or take control over data-retrieval process to fine tune performance.

Directives in AngularJS templates declaratively express the desired effect, so we are freed from providing step-by-step instructions on how to change individual properties of DOM elements (as is often the case in applications based on jQuery). AngularJS heavily promotes declarative style of programming for templates and imperative one for the JavaScript code (controllers and business logic). With AngularJS , we rarely apply low-level, imperative instructions to the DOM manipulation (the only exception being code in directives).

Tip As a rule of thumb, one should never manipulate the DOM elements in AngularJS controllers. Getting a reference to a DOM element in a controller and manipulating element's properties indicates imperative approach to UI - something that goes against AngularJS way of building UIs.

Declarative UI templates written using AngularJS directives allow us to describe quickly complex, interactive UIs. AngularJS will take all the low-level decisions on when and how to manipulate parts of the DOM tree. Most of the time AngularJS does "the right thing" and updates the UI as expected (and in a timely fashion). Still, it is important to understand the inner workings of AngularJS, so that we can provide appropriate hints to the framework if needed. Using the SQL analogy once again here, most of the time we don't need to worry about the work done by a query planner. But when we start to hit performance problems, it is good to know how query planner arrived at its decisions so that we can provide additional hints. The same applies to UIs managed by AngularJS: we need to understand the underlying machinery to effectively use templates and directives.