Click here to Skip to main content
Click here to Skip to main content

Databinding in Windows 8 JavaScript Metro Style Apps

By , 4 Jul 2012
 

This blog was originally posted here: Databinding in Windows 8 JavaScript Metro style Apps

Also, check out our Windows 8 sponsored section.

[NOTE: This post was written using the Visual Studio 11 beta and Windows 8 Consumer Preview ... as with any pre-release software, the code and concepts are subject to change in future versions]

One of the nice features of the new JavaScript Windows Metro style app templates in the Visual Studio 11 beta is that they provide built-in support for databinding, using sample data in a JSON array. Folks who have experience in the XAML world may not see this as a particularly big deal, since Silverlight and WPF have supported databinding for a long time.

For web applications, however, data binding is still a concept that's evolving. While there are third-party libraries like Knockout.js that provide client-side databinding (and my fellow DE David Isbitski recently published a blog post detailing how you can use Knockout in a Metro style app, if that's your cup of tea), but in general the web world is a little behind the curve compared to XAML-based databinding.

Back to Windows 8, both the Grid Application template and the Split Application template include markup and code that demonstrates databinding to sample data contained in a file called data.js (in the js folder off the root of the app). The data.js file contains static sample data stored as JSON arrays, along with some helper functions that expose (via WinJS.Namespace.define) the collections of items, groups, and items from a specified group. This data is used by the binding templates in the HTML markup included in the application templates, such as itemsPage.html in the Split Application template.

As with most generated JavaScript files in the Metro style app templates, data.js uses a self-executing anonymous function to wrap the code that defines the sample data. This both ensures that the code that creates the JSON data (and related helper code) executes as soon as data.js is loaded, and also hides the internal variables declared in data.js so that they do not pollute the global JavaScript namespace.

Both application templates use the same sample data, which has the following schema:

sampleGroups

  • key
  • title
  • subtitle
  • backgroundImage (maps to one of 3 variables containing a base64 encoded png image)

sampleItems

  • group (maps to sampleGroups above)
  • title
  • subtitle
  • description (maps in the sample data to the itemDescription variable)
  • content (maps in the sample data to the itemContent variable)
  • backgroundImage (maps to one of 3 variables containing a base64 encoded png image)

In addition to declaring sampleGroups and sampleItems as JSON arrays, data.js creates a WinJS.Binding.List called list, and then calls its createGrouped method (passing in the parameters for grouping, which in this case are functions that return the group key and group), and finally loops through the sampleItems array using forEach, and adds each item to the binding list object.

Once the binding list(s) are available, they are typically bound to the HTML markup either declaratively with attributes or programmatically in JavaScript. For example, in the itemsPage.html file of a Split application, the default UI for displaying the groups is a ListView control, which is implemented as a div element with the data-win-control attribute set to WinJS.UI.ListView:

<div class="itemslist" aria-label="List of groups" 
    data-win-control="WinJS.UI.ListView" 
    data-win-options="{ selectionMode: 'none' }">
</div>

(Note that in order for the data-win-control attribute to convert the div element into a ListView control, the app must call WinJS.UI.processAll(), which is done by default in default.js in the Grid and Split application templates)

In the case of the Split application template, the JavaScript file for itemsPage.html, which is named itemsPage.js contains the following code in the ready handler which sets the datasource of the ListView to the groups defined in the sample data:

   1:  var listView = element.querySelector(".itemslist").winControl;
   2:  ui.setOptions(listView, {
   3:      itemDataSource: data.groups.dataSource,
   4:      itemTemplate: element.querySelector(".itemtemplate"),
   5:      oniteminvoked: this.itemInvoked.bind(this),
   6:  });

(In the code above, UI is an alias to WinJS.UI)

The code above gets a reference to the ListView control by querying for the class name associated with the control, and then passes that object into the call to WinJS.UI.setOptions, setting the itemDataSource to data.groups.dataSource (which is the dataSource property on the WinJS.Binding.List object), and the itemTemplate to the item template defined in the markup (again, obtained by querying for the matching class name).

Here's what the item template looks like:

<!-- This template is used to display each item in the ListView declared below. -->
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
    <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" />
    <div class="item-overlay">
        <h4 class="item-title" data-win-bind="textContent: title"></h4>
        <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
    </div>
</div>

Notice again the use of the HTML5 data- attributes, in this case both data-win-control to define the outside div element as a WinJS.Binding.Template, and the data-win-bind attributes to define the relationship between attributes of the individual elements (for example, the src attribute of the img element) and the values to which they're being bound (in the case of the img element, the src attribute is bound to the backgroundImage property, and the alt attribute is bound to the title property).

Once the code in the ready handler has executed, the call to WinJS.UI.processAll() from default.js will complete the binding process, and you should see something like the following:

Databinding in JavaScript Windows Metro style apps is easy and straightforward, and having a template that provides a clear implementation with sample data can help you get started with your own application. This post just scratches the surface, but I wanted to walk through the basics of the databinding implementation before delving deeper into topics like customization and binding converters, which I'll cover in future posts.

If you just can't wait, here's a list of additional resources that will help you dig deeper into databinding in JavaScript Metro style apps:

Additional Resources

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

G. Andrew Duthie
United States United States
Member
Andrew is a Developer Evangelist for Microsoft Corporation, covering the Mid-Atlantic states. He has been working with computers since the days of the Commodore PET, hacking game programs loaded from cassette tapes to say funny stuff, and has been writing and speaking about developer technologies for more than a decade. While his developer specialty is web development, Andrew also enjoys gadgets of any stripe, gaming, cigars, and poker. In his free time he can be found spending time with his wife and two sons, reading, or playing music.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 4 Jul 2012
Article Copyright 2012 by G. Andrew Duthie
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid