WinRT JavaScript - Templates & Data Binding
Written by Mike James   
Wednesday, 18 January 2012
Article Index
WinRT JavaScript - Templates & Data Binding
Templates and data
Data binding

The Template object is useful in its own right but add it to data binding and you have a easy to use way to present data to the user.  It also happens to be the easiest way to find out about data binding in general.

Articles on WinRT JavaScript

  1. Getting Started
  2. WinControls
  3. Templates & Data Binding (this article)

 

In the previous part of this series of articles on WinRT JavaScript we looked at how to use WinJS custom controls. In this third part we look at one of the more interesting custom control - the Template and introduce the databinding mechanism.

The Template is useful whenever you need to create multiple copies of the same HTML and content. You could, for example, use it to generate the lines in a table structure. This is useful but not super useful. However, if you add data binding to the Template object it all becomes so much more useful. With data binding you can not only "stamp out" lines in a table, you can also automatically fill them in. The databound Template is a natural way to create any table or list of data automatically and with minimal fuss.

So let's get started.

It is assumed that you know how to work with a WinRT JavaScript project and know the basics of HTML/CSS as described in Part One. It is also assumed that you know how custom controls work as described in Part Two.

The Template

The basic Template control is a very simple thing. All it does is to contain any HTML you care to fill it with. When the Template control is initialized its only action is to hide its contents. This may sound like a strange thing to do but you don't want the Template itself showing on your page until you are ready to make a copy of it and place it where you want it.

Start a new blank project and edit the default.html page to load the following scripts. The only new one from part two is binding.js which is needed for the Template object:

<script type="text/javascript" 
src="/WinJS/js/base.js"></script>
<script type="text/javascript"
src="/WinJS/js/ui.js"></script>
<script type="text/javascript"
src="/WinJS/js/binding.js"></script>
<script type="text/javascript"
src="/WinJS/js/controls.js"></script>
<script type="text/javascript"
src="/WinJS/js/wwaapp.js"></script>

Next we need to create a Template element using the standard approach introduced in Part Two, i.e. using the data- attribute. As the template represented by the Template object is composed of whatever HTML you care to put between its tags, let's just use a Div with some dash characters to represent a horizontal line - not particularly useful but easy to understand.

Our Template in HTML is just:

<div id="Mytemplate" data-win-control=
"WinJS.Binding.Template">
<div>--------------</div>
</div>

If you run the program at this point you will see a single line of dashes at the location of the Template div - after all why would you see anything else?!

 

dash0

To make the Template do its magic we have to invoke the JavaScript code that scans the DOM and implements the Template Object in JavaScript. All we have to do is call the usual processAll function to convert elements with data-win-control attributes into controls (see part 2). You can add this call to either the onmainwindowactivated or the DOMContentLoaded event handler:

document.addEventListener("DOMContentLoaded", 
function (e) {
WinJS.UI.processAll();
...

If you now run the program you will discover that the contents of the Template element have gone missing i.e.you now can't see the dashed line.

blank

This is general behaviour Templates hide their contents when converted into custom controls.

The next step is to do something useful with our Template.The key idea here is that the Template object has a render method which instantiates the contents of the Template as a DOM sub-tree. 

So for example to create an instance of the content of our Template, i.e. a single <div> with a dashed line for its text node all we have to do is call the Templates render function - but there are two complications. First we need to get the JavaScript object that corresponds to the Template object and has the render method. This is easy:

var template = WinJS.UI.getControl(
document.getElementById("Mytemplate"));

Now we can call the render method:

template.render();

As is the way with most WinRT methods it does not return the result but a Promise object. The reason is that in principle rendering a template could take a long time and so the render method is implemented as an asynchronous call and so returns a Promise object.

There are many things to say about Promise objects but for the moment the only thing we need to know is that you can use the promise.then() method to call a function when the task is  completes successfully  and an optional second function to be called if it fails.

So the entire process of rendering the template is:

template.render().then(function(element){
...
});

and the rendered DOM subtree is returned as the element parameter  and we can write some code to work with it.

So now we have a rendered Template what do we do with it?

In most cases the answer is that we add it to some existing element in the HTML. For example if we add a div with id Display:

<div id="Display">
</div>

and now after the render method completes we can simply add the result to the DOM within the div:

var display= 
document.getElementById("Display");
display.appendChild(element);

The entire HTML is:

<body>
<div id="Mytemplate" data-win-control=
"WinJS.Binding.Template">
<div>--------------</div>
</div>
<div id="Display">
</div>
</body>

and the JavaScript is:

document.addEventListener("DOMContentLoaded", 
function (e) {
WinJS.UI.processAll();

var template = WinJS.UI.getControl(
document.getElementById("Mytemplate"));
template.render().then(
function(element){
var display=
document.getElementById("Display");
display.appendChild(element);
});
});

Now if you run the program you will once again see a dashed line:

dash1



Last Updated ( Wednesday, 18 January 2012 )