Corrado's Blog 2.0

Online thoughts of a technology funatic

Two-way binding in WinJS

As many of you who couldn’t attend Build 2012 I’m watching recorded sessions posted on Channel 9.

I really enjoyed the Deep Dive into WinJS session and the trick to solve one of the big missings of WinJS databinding: the lack of Two-way support.

Let’s start with a simple default.html page:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>TwoWayBinding</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>

    <!-- TwoWayBinding references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
    <style>
        input[type=text]
        {
            width: 300px;
            height: 50px;
            margin-left: 10px;
        }
        .host {
            margin-top: 50px;
            margin-left: 50px;
        }
    </style>
</head>
<body>
    <div class="host">
        <span class="win-type-x-large">Enter Value</span>
        <input type="text" data-win-bind="value: name" />
    </div>
</body>
</html>

Nothing special here, just a textBox bound to a “name” property.

Let’s create the source data inside default.js file, below only onactivated function is listed for brevity since the rest is exactly the same code generated by Visual Studio template:

app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {

            WinJS.Namespace.define("Data", {
                Person: {
                    name: "fabio"
                }
            });

            var src = WinJS.Binding.as(Data.Person);
            WinJS.Binding.processAll(null, src);
            src.bind("name", function (newValue) {
                console.log("Value is " + newValue);
            });

            args.setPromise(WinJS.UI.processAll());
        }
    };

As you see I created a Person class inside “Data” namespace, made it observable, and added tracking for “name” property updates using bind function.

Running the code, you’ll get, as expected,  a textbox filled with initial name “fabio”:

image

If we now type something inside textbox, you’ll see that no value change is tracked since, by default, WinJS binding is one-way only.

We all know how valuable is having two-way binding,  especially if you are a MVVM/KnockoutJS fan.

Luckily it is quite easy to achieve it, at least in its simplest form thanks to Binding Initializers that is a function that is invoked when binding is created, usually the invoked function is WinJS.Binding.defaultBind that creates the one-way binding.

Binding Initializers give you access to both source and target objects and their properties, this allow us to subscribe to target element’s events and push data to source object.

Here’s initializer definition:

WinJS.Namespace.define("Binding.Mode", {
                twoway: WinJS.Binding.initializer(function (source, sourceProps, dest, destProps) {
                    WinJS.Binding.defaultBind(source, sourceProps, dest, destProps);
                    dest.onchange = function () {
                        var d = dest[destProps[0]];
                        var s = source[sourceProps[0]];
                        if (s !== d) source[sourceProps[0]] = d;
                    }
                })
            });

Initializer is defined using WinJS.Binding.initializer object and passing a function that receives binding properties, inside the function we use WinJS.Binding.defaultBind to create a standard one-way binding then we subscribe target (textbox) onchange event and when it triggers we update source object.

Once defined, all we need is to apply the initializer to binding this way:

<input type="text" data-win-bind="value: name Binding.Mode.twoway" />

Running the app and typing something inside textbox, will now result in new value printed inside console window, confirming that source has been updated

image

Technorati Tags: ,

Using Word 2013 as blog post editor

Never been a huge fan of Windows Live Writer, and since there’s no WinRT version yet, I am trying to use Word 2013 as blog post editor.
Having Word full editing power is awesome, and it looks like that it works really well with my WordPress blog.

There is nothing hard to use Word 2013 as editor with WordPress, just use [your blog url]/xmlrpc.php as url together with your credentials and you’re done! J