Control Manipulation: Function Rendering


Earlier we worked with collection controls like the ListView. Now we'll work with collection controls in a different way, using Function Rendering. Function Rendering is the concept of creating collection controls using functions instead of declarative templates. This is important because it lets you control when different items in your collection get rendered. This helps enhance your templates if declarative templates are not sufficiently expressive. This asynchronous loading could be important if, for example, you had a phonebook application and you wanted to load all of the contacts quickly with or without the images – you could load the names and phone numbers and delay the image information!

Your template function can be specified in any control property that expects a renderer, such as data-win-options. Just remember to use the WinJS.Utilities.markSupportedForProcessing or WinJS.UI.eventHandler (refer to Basics: Mark Support) with a promise!

When you are developing your function, it needs to be created as an object within the window global object. This is necessary because the function needs to be passed in using a NameSpace or a global object, and the window object is already a given.

Here is an example of how to create an object within the window Namespace:

var App = window.App = {};

Here is how to create the object within the window Namespace to gain access to the functions in the HTML.

function itemTemplateFunction(itemPromise) {
    return itemPromise.then(function (item) {
        var div = document.createElement("div");
        div.className = "mediumListIconTextItem";

        var img = document.createElement("img");
        img.src = item.data.picture;
        img.alt = item.data.title;
        img.className = "mediumListIconTextItem-Image";
        div.appendChild(img);

        var childDiv = document.createElement("div");
        childDiv.className = "mediumListIconTextItem-Detail";

        var title = document.createElement("h4");
        title.innerText = item.data.title;
        childDiv.appendChild(title);

        var desc = document.createElement("h6");
        desc.innerText = item.data.text;
        childDiv.appendChild(desc);

        div.appendChild(childDiv);

        return div;
    });
};

App.itemTemplateFunction = itemTemplateFunction;
WinJS.UI.eventHandler(TemplatingExample.itemTemplateFunction);
App.itemList = new WinJS.Binding.List(/*insert array here*/);

And this creates a ListView that uses the templating function:

<div id="templatingFunctionListView" data-win-control="WinJS.UI.ListView"
    data-win-options="{itemDataSource : App.itemList.dataSource,
                       itemTemplate : App.itemTemplateFunction }">
</div>

Here you will notice that this example retrieves a ListView named templateFunctionListView (you can see above) and sets its itemTemplate property with an item template function that displays the title, text and picture of each data item. The example then goes on to create a Namespace for this rendering function and uses markSupportedForProcessing() to give the function permission to run without security issues.

Everything uses Function Rendering

The exciting thing about function rendering is that even when you are creating a template declaratively, it is still using a rendering function behind the scenes! We stated before that the default render function is Template.render.