Source code on GitHub

In this post we will learn how to work with the data binding and observable class in the Windows Store application created using WinJS. We will learn to work with

  • Data binding
  • Two way data binding
  • Observable object

By default WinJS

  • Provides one way binding
  • When the data source is updated HTML element gets updated
  • Updated value of HTML element does not update the data source.

Let us start with working with a basic data binding example. So I have a JavaScript object as shown below,


var student = { name: "Dj" };

We can perform data binding in winJS using data-win-bind attribute on the HTML element.

clip_image002

In above code snippet we are using data-win-bind attribute to bind span inner text with the name property of the student object. As of now HTML is very simple and looks like as follows:


<body>
     <div id="welcome">
        Welcome,
        <span id="nameSpan"
              data-win-bind="innerText: name">
        </span>
    </div>

</body>

As the last step of the data binding we need to call WinJS.Binding.processAll() by passing the data source and the target HTML element. Make sure that you call this after the execution of all the activation codes.


    var personDiv = document.querySelector('#nameSpan');
    WinJS.Binding.processAll(personDiv, student);

Essentially we are selecting the element using the document.querySelector and the in the process all function passing the target element and the data source as a data context. By now we have successfully data bind html element to the data source. On running the application you should get output as follows

clip_image002[6]

So far we have done one way binding and if data changes at the data source target element won’t get any notification. We can convert a data context to a binding context using the WinJS.Binding.as. To understand this in better way let us start looking at a problem statement. I have modified the UI as follows,


<body>
    <div id="welcome">
        Welcome,
        <span id="nameSpan"
              data-win-bind="innerText: name">
        </span>
        <br/>
        <input type="text" id="txtInput" />
        <button id="btnUpdataDs">Update DataSource</button>
    </div>

</body>

Now UI look like as follows and when we enter a value in the text box that should update the welcome span.

clip_image002[8]

On the click event of the button we can modify name property as follows


document.querySelector("#btnUpdataDs").onclick = function () {

           var updatedname = document.querySelector('#txtInput').value;
           student.name = updatedname;
        }

When run the application you will find that value of the welcome span is not getting updated. Reason behind is that when data source is getting updated it does not send any notification to the target elements bind to it. WinJS gives us a method to create notification on the data source and convert it to a binding context. You need to use WinJS.Binding.as to create binding context.

So let us modify the above code to perform two way binding,

var personDiv = document.querySelector('#nameSpan');
        WinJS.Binding.processAll(personDiv, student);
        var bindingSource = WinJS.Binding.as(student);
        document.querySelector("#btnUpdataDs").onclick = function () {

           var updatedname = document.querySelector('#txtInput').value;
           bindingSource.name = updatedname;
        }

In above code there is only one extra added line

clip_image002[10]

Now on running the application you will find that when you change the value in text box and click on update data source value of welcome span will also be changed.

clip_image004

WinJS data bind allows us to to do binding of styles as well. Let us go ahead and add one more property to set the color of the text. Updated data source is as follows:

 


   var student = {
        name: "Dj",
        color: "red"
     };

And we can bind color to the welcome span as follows


<span id="nameSpan"
              data-win-bind="innerHTML: name;
               style.background: color ">
        </span>

And we can update value of color as follows

var personDiv = document.querySelector('#nameSpan');
        WinJS.Binding.processAll(personDiv, student);
        var bindingSource = WinJS.Binding.as(student);
        document.querySelector("#btnUpdataDs").onclick = function () {

           var updatedname = document.querySelector('#txtInput').value;
           bindingSource.color = updatedname;
        }

Now let us see that how can we bind to a complex object. We will start with creating a complex object. Working with complex object can be summarized into following steps

  1. Create the class
  2. Add _initObservable method in the constructor of the class
  3. Make class observable by using the WinJS.Class.mix
  4. Create instance of the object
  5. Use bind methods to bind the properties
  6. Use the object in the binding

Let us start with creating a Student class

 


var Student = WinJS.Class.define(
       function()
       {

           this.name = "DJ";
           this.size = "16px";
       },
       {

           _names:
               ["foo", "loo", "koo", "too", "moo", "soo", "aoo", "too", "qoo", "coo"],
           _sizes:
               ["30px", "80px", "40px","20px","35px","67px","43px","23px","54px","12px"],

           _newName: function () {
               this["name"] = this._names[this._randomizeValue(this._names.length)];
               this["size"] = this._sizes[this._randomizeValue(this._sizes.length)];
           },
           _randomizeValue: function (max) {
               return Math.floor((Math.random() * 1000) % max);
           }

       });

In this class we have put two arrays and two functions. In the constructor of the class we are setting default value for name and the size. _newName function will return new name from the array with new size from the size array.

Next we need to add _initObservable inside the constructor. So updated constructor will look like as follows:

 


  var Student = WinJS.Class.define(
       function()
       {
           this._initObservable();
           this.name = "DJ";
           this.size = 16;
       },

Now to make the object observable we need to use WinJS.Class.mix. This can be done as follows:


    WinJS.Class.mix(Student,
    WinJS.Binding.mixin,
    WinJS.Binding.expandProperties({name: "", size: ""})
);

After this step we need to call the bind method on the instance of the Student class. Make sure to create instance in the app.onactivated event handler.

 

            var s = new Student();
            s.bind("name",onNameChange);
            s.bind("size", onSizeChange);

The bind method takes two parameters. First name of the property and second parameter as the function which will define how property will be bind. Below we have function calling on the bind.


function onNameChange (newValue) {
        var span = document.getElementById("nameSpan");
        span.innerText = newValue;
    };

    function onSizeChange (newValue) {
        var span = document.getElementById("nameSpan");
        span.style.fontSize = newValue;
    };

On the HTML markup is bind to properties of Student and there a button. On click event of the button we will call _newName function on the student object to change the name and the font size.


   <div id="welcome">
        Welcome,
        <span id="nameSpan"
              data-win-bind="innerHTML: name;
               style.fontsize: size ">
        </span>
        <br/>
        <button id="btnUpdataDs">Update DataSource</button>
    </div>

On the click event of the button we will call _nameName function as shown below:

document.querySelector("#btnUpdataDs").onclick = function () {

            s._newName();
        }

When you run the application on the click of the button name and size of the name should change. Data binding and the observable are very important components of WinJS and you may want to use them while create app for the Windows Store.

Source code on GitHub

Happy Coding.

Advertisements

One thought on “Data Binding and Observable in WinJS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s