type

script

the script tag must contain an id attribute with a unique value.</ul> To use the template defined within a script tag we add an ng-include directive to the parent element whose value is the ID of the template. Thus if the ID of the template is person.html then the directive must be

Important: Please not the single quotes around person.html. The value of the ng-include is an expression and to indicate to Angular that person.html is a string value we need to put those single quotes around it.

That said, our view now looks like this

Structural HTML has been separated from specific layout parts. If you refresh the page in the browser after these changes the output should look exactly the same way as before. Although here in this very simple sample it is not really evident what the benefit should be, just believe me that the true beauty of this principle comes to shine in more complex situations.

Note that all the templates that you define with the technique shown above are stored in the Angular template cache and they are available to you at any time via the $templateCache service.

If we have more and more different templates we want to use and the templates become more and more complex it makes sense to store them in their own individual files. Let’s just do that and extend our sample. On our view we output a second list of the same persons but this time we are using a template person2.html stored as a file in a subfolder called templates. The HTML we add to our main view (index.html) looks like this

And the content of the file person2.html might look like this (to not use the very same boring layout as in the above template)

Note that I use a CSS class person which is defined as

The above definition resides in a file app.css that I reference in the header of my index.html

Finally when refreshing the browser we get this result

The advantage is now that I can go and significantly change the layout of each person item in the list without having to touch the index.html view. Let’s just do this for fun and add an icon to each person which is depending on the gender of the person. To make things simple I just went quickly on Bing and searched for small male and female symbols and stored them as M.jpeg and F.jpeg respectively in the same folder as the index.html. Then we can change the template person2.html as follows

Please not the usage of the ng-src directive in the img tag. It allows me to use data binding. In my case I use the content of the gender property on our model to determine which image to use. For a nicer looking list I also fix the width of the image to 25 pixels. The result of which is

Dynamic templates

What if we want to display a list of items where we need a different template for each of the items? How can we handle that? Let’s take the sample of a (simple) questionnaire to analyze this problem. A questionnaire is a document that has a series of questions where the user is required to fill in answers for each question. The type of question determine what kind of answer the user has to provide. Is it a plain text, a numeric, a date type or multiple choice answer? Certainly you can imagine many more types or categories of answers. We want to show the questionnaire as a list of questions and have each question display the answer part according to the type or category of question.

Let’s start with the controller where we define on its $scope a simple pre-canned questionnaire.

Now let’s define the HTML that outputs the questionnaire as a series of div tags. For a first iteration we only want to print the question number, type and text.

The CSS is

Nothing spectacular so far, but at least we get the expected result.

Now comes the interesting part. To each of the questions we want to define an area where the user can answer the corresponding question and as we have noted above each question has a different kind of answer layout, depending on the type of question. Let’s realize this by defining a template per question type. We will create a file per template and will name the file like the type of the question, e.g. number.html, text.html, etc.

text.html

number.html

date.html

singleOption.html

multiOption.html

And we need to modify the main template slightly too

Note specifically how we leverage the fact that the ng-include value is interpreted as expression by Angular and as such we can combine data binding (question.type) and string concatenation to generate the URL to the template to load.

The CSS class answer is defined as follows

Once we have defined all these templates the output in the browser is as follows

As expected each question has its own individual answer layout.

In a real application each template would probably have its own controller containing the workflow logic for the appropriate question; but this lies outside of the scope of this post which is already pretty long.

Recursive templates

Sometimes we want to display templates that in turn reference other templates which again might reference more templates. These are called recursive templates. A very good sample for this is a tree where a root node has children which in turn are nodes and have children and so on. How would we display such a tree? If we hardcode such a tree in HTML it could look like this

That is, just a series of nested unordered list which in the browser are displayed like this

It is evident that this does not work for any arbitrary tree structure e.g. loaded from a backend server. Luckily Angular provides us with the possibility to define recursive templates. Let’s just start and see how to do that. First we define a new TreeCtrl controller having a pre-canned tree structure defined on its $scope.

Let’s now do a first implementation of the view. We add the following HTML snippet to the index.html

This of course will only show us the list of parents since we have not yet defined any recursion. To do that we need to use templates. We will define the template directly inside the index.html by using the special script tag

After this modification the result is still the same but now we can start to extend our new node template and add recursion to it. We do not only want to display the name of the current node but also a nested list of all children of the current node. Nothing easier than that

Note how in the nested list the ng-repeat directive is used to iterate over all children of the current node and how the ng-include directive is used to self reference the template. And the output is as expected

Conclusions

Templates come in very handy whenever we want to separate pure structural or semantic layout from more specific layout of certain UI fragments. In this regard using templates helps us in adhering to the single responsibility principle.

In this post I have discussed in detail three categories of templates – static, recursive and dynamic templates. We make heavy use of each category in our complex enterprise solution. In this post I have only scratched on the surface on what is possible when using templates as supported by Angular.

The code to this series can be found on GitHub.