Quickstart: binding data and styles (HTML)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

You can bind data and styles to HTML elements by using Windows Library for JavaScript binding. Binding with WinJS is one-way by default, which means that the HTML element is updated when the data and style values change, but the data is not updated when the HTML element changes. This quickstart shows the most basic kind of binding, which is a declarative binding to a simple object that contains only data. For information about more advanced kinds of binding, see How to bind a complex objectand How to use templates to bind data.

Prerequisites

This topic assumes that you can create a basic Windows Runtime app using JavaScript. For instructions on creating your first app, see Creating your first app using JavaScript.

Setting up a binding project

To set up a project to use binding, complete these steps.

  1. Create a new blank Windows Runtime app using JavaScript and name it BindingApp.

  2. In default.html, add a DIV element for the binding, and give it an ID of "basicBinding" and an inner text of Welcome, as shown here.

    <body>
        <div id="basicBinding">
          Welcome
        </div>
    </body>
    

Binding data

You can bind any kind of data to an HTML element, but for purposes of illustration we'll just set up a person object that has a field for a first name.

Warning  Do not attempt to bind data to the ID of an HTML element.

 

  1. In default.js, add the following line of code inside the immediately-invoked anonymous function, right after the use strict directive.

    (function () {
        "use strict";
    
        // Create a 'person' object.
        var person = { name: "Fran" };
    
        // Other app set-up code.
    })();
    
  2. Inside the DIV element, add a SPAN element that accesses the person.name field.

    <div id="basicBinding">
        Welcome, 
        <span id="nameSpan" data-win-bind="innerText: name"></span>
    </div>
    
  3. You must call WinJS.Binding.processAll to have the name appear. WinJS.Binding.processAll starts looking for the data-win-bind attribute at the specified element and then searches all the descendants of that element. The second parameter of WinJS.Binding.processAll provides the data context to inject into the specified element. Add the following code inside the app.onactivated event handler in default.js.

    app.onactivated = function (args) {
    
        // Other activation code ...
    
        var personDiv = document.querySelector('#nameSpan');
        WinJS.Binding.processAll(personDiv, person);
    }
    
  4. When you build and debug the project, you should see this:

    Welcome, Fran

  5. Consider the following code fragment:

    
    app.onactivated = function (args) {
    
        // Other activation code ...
    
        var personDiv = document.querySelector('#nameSpan');
        WinJS.Binding.processAll(personDiv, person);
        var bindingSource = WinJS.Binding.as(person);
    }
    
    • The WinJS binding system uses an observable layer to propagate change notifications.
    • When you pass a data object into processAll as the data context it is wrapped in a call to WinJS.Binding.as which creates or rendezvouses with an already created observable proxy for that object.
    • All "writes" (that is, property set’s) that you want to fire notifications for need to occur through this proxy layer, you can rendezvous with the observable proxy via WinJS.Binding.as later.
    • Frequently the easiest thing to do is simply to use that observable proxy as your object for reading and writing data.
    • One-time binding occurs when using a binding initializer to override the default behavior (such as WinJS.Binding.oneTime) or attempt to bind against objects which are non-extensible (such as frozen, or WinRT projected objects).
  6. To demonstrate what happens when the underlying data changes, we'll just use a button to simulate getting data from a different process or from an internal data store. Add a BUTTON element to default.html, below the DIV.

    <button id="btnGetName">Get name</button>
    
  7. Add a mock method that simulates getting the data. In this case, we'll get the name from an array by using a randomized index. In default.js, add the following code to the app.onactivated event handler that handles the click event of the button.

    document.querySelector("#btnGetName").onclick = function () {
                getName(bindingSource, nameArray);
        }
    
    var nameArray =
            new Array("Sally", "Jack", "Hal", "Heather", "Fred", "Paula", "Rick", "Megan", "Ann", "Sam");
    
    function getName(source, nameArray) {
        source.name = nameArray[randomizeValue()];
    }
    
    function randomizeValue() {
        var value = Math.floor((Math.random() * 1000) % 8);
        if (value < 0)
            value = 0;
        else if (value > 9)
            value = 9;
        return value;
    }
    
  8. To test this code, build and debug the application. You should see a different name every time you click the Get name button.

Binding a style

Now we'll bind the background color of the SPAN element.

  1. In default.html, add a style.background value to the data-win-bind attribute, and set its binding to the color field of the person object.

    <div id="basicBinding">
        Welcome, <span id="nameSpan" data-win-bind="innerHTML: name; style.background: color"></span>
    </div>
    
  2. In default.js, add a color field to the person object.

    Tip  The left-hand-side of a binding expression is any property on an element and its sub properties using JavaScript syntax (that you would use to assign to it programmatically).

     

    var person = { name: "Fran", color: "red" };
    
  3. Also in default.js, in the app.onactivated event handler, add a second array of colors and change the getName function to so that it updates the color of the name.

    var colorArray =
        new Array("lime", "lavender", "yellow", "orange", "pink", "greenyellow", "white", "lightblue","lightgreen", "lightyellow");
    
    function getName(source, nameArray, colorArray) {
        source.name = nameArray[randomizeValue()];
        source.color = colorArray[randomizeValue()];
        }
    
  4. Remember to change the getName call in the click event handler for the button.

    document.querySelector("#btnGetName").onclick = function () {
                getName(bindingSource, nameArray, colorArray);
        }
    
  5. When you build and debug the app, you should see that clicking the Get name button updates both the name and the color of the name.

Summary and next steps

In this quickstart, you saw how to bind a simple JavaScript object to an HTML span.

To find out how to bind more complex objects, see How to bind a complex object. If you want to use a template to bind multiple objects, see How to use templates to bind data.