Some Q&A I've collected recently. Enjoy.
 

Q: I'm trying to bind part of a ListView item template to the result of a method in a class, but the function text itself is appearing instead of the result. How can I make this work?

A. Here's the context for the question. Say we have a simple binding declaration as follows:

<div data-win-bind="textContext: FullName"></div>

And we're binding to a class that looks like this:

var _MyClass = WinJS.Class.define(
    function () {
        this.FirstName = "";
        this.LastName = "";
    },
    {
        FirstName: "",
        LastName: "",
        FullName: function () {
            return this.FirstName + ' ' + this.LastName;
        }
    }
);

The issue is that binding to FullName doesn't execute the function, but just binds to the function object. There aren't problems binding to FirstName and LastName as those are just properties.

The solution here is to make FullName a property as well, rather than a function, which can be done as follows:

FullName: {
    get: {
        return this.FirstName + “ “ + this.LastName;
    }
}

[Thanks to Dominic Hopton]

 

Q. Is it possible from JavaScript to bind to data in a WinRT component?

A. Yes. The trick is that you need to use WinJS.Binding.oneTime as the initializer in the binding syntax. For a full discussion, see Mike Taulty's blog: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2012/04/26/windows-8-metro-style-bits-of-binding.aspx

 

Q. Is it possible to use WinJS data binding on styles and other non-text elements?

A. Yes it is. In general you can use the syntax data-win-bind="style.<target_property>: <source_property>", and for styles like font-weight and text-decoration that don't work with dot notation you can use []'s as in data-win-bind="style[target-property]: <source_property>".

Phil Japiske has a good post on this subject on Telerik's blog: http://blogs.telerik.com/Windows8Team/posts/13-12-27/setting-html-styles-with-binding-in-windows-8-winjs-apps 


Continuing from Part 1, to implement an binding initializer function directly looks like this, which is taken from scenario 1 of the Declarative binding sample (for 8.1):

var toCssColor = WinJS.Binding.initializer(
function toCssColor(source, sourceProperty, dest, destProperty) {
function setBackColor() {
dest.style.backgroundColor =
rgb(source.color.red, source.color.green, source.color.blue);
}

        return WinJS.Binding.bind(source, {
color: { red: setBackColor, green: setBackColor, blue: setBackColor, }
});
}
);

// A little helper function to convert from separate rgb values to a css color
function rgb(r, g, b) { return “rgb(” + [r, g, b].join(“,”) + “)”; }

WinJS.Namespace.define(“BasicBinding”, {
toCssColor: toCssColor
});

WinJS.Binding.initializer is just an alias for WinJS.Utilities.markSupportedForProcessing, which It makes sure you can reference this initializer from processAll and doesn’t add anything else where binding is concerned.

The arguments passed to your initializer clearly tell you which properties of source and target (dest) are involved in this particular relationship. The source argument is the same as the dataContext given to processAll, and dest is the element on which this particular initializer was declared (which can be anywhere below the rootElement given to processAll). The sourceProperty and destProperty arguments are both arrays that contain the “paths” to their respective properties, where each part of the identifier is an element in the array. That is, if you have an identifier like style.color in data-win-bind, the path array will be [style, color].

With all this information in hand, you can then set up whatever binding relationships you want by calling the source’s bind method with whatever properties and handlers you require. Note that although sourceProperty is what’s present in the data-win-bind attribute, you’re free to wire up to any other property you want to include in the relationship. The code above, for example, will be called with sourceProperty equal to [color], but it doesn’t actually bind to that directly. It instead uses a binding descriptor with WinJS.Binding.bind to hook up the setBackColor handler to three separate color subproperties. Although setBackColor is used for all three, you could just as easily have separate handlers for each one if, for example, each required a unique conversion.

Ultimately, what’s important is that the handler given to the source.bind method performs an appropriate update on the target object. In the code above, you can see that setBackColor sets dest.style.backgroundColor.

Hmmm. Do you see a problem there? In the Declarative binding sample, try changing the last data-win-bind attribute in html/1_BasicBinding.html to set the text color instead:

data-win-bind=”style.color : color BasicBinding.toCssColor”

Oops! It still changes the background color! This is because the initializer isn’t honoring destProperty, and that would be a difficult bug to track down when it didn’t work as expected. Indeed, because the initializer pays no attention to destProperty you use a non-existent identifier and it will still change the background color:

data-win-bind=”some.ridiculous.identifier : color BasicBinding.toCssColor”

Technically speaking, then, we could rewrite the code as follows:

dest.[destProperty[0]].[destProperty[1]] = rgb(source.color.red, source.color.green, source.color.blue);

Even this code makes the assumption that the target path has only two components—to be really proper about it, you need to iterate through the array and traverse each step of the path. Here’s a way to do that:

var target = “dest”;
for (var i = 0, len = destProperty.length – 1; i < len; i++) {
target += “.” + destProperty[i];
}

target = eval(target);
var lastProp = destProperty[i];

function setBackColor() {
target[lastProp] = rgb(source.color.red, source.color.green, source.color.blue);
}

Note that I’m building that reference outside of the setBackColor handler because there’s no need to rebuild it every time a source property changes.

Remember also that sourceProperty can also contain multiple parts, so you may need to evaluate that path as well. The sample gets away with ignoring sourceProperty because it knows it’s only using the toCssColor initializer with source.color to begin with. Still, if you’re going to write an initializer, best to make it as robust as you can!

 

[7/23/13: Corrected one statement above on the source and dest arguments to the initializer. It has incorrectly stated that dest was the same as the rootElement to processAll; it’s the element where the initializer is declared.]


I’ve been writing about this subject more thoroughly for the second edition of my book (view preview here), and thought to share the results here in two parts.

When WinJS.Binding.processAll encounters a data-win-bind attribute on an element, its main job is to take each <target property> : <source property> [] string and turn it into a real binding relationship. Assuming that the data source is observable, this basically means calling the source’s bind method with the source property name and some handler that will update the target property accordingly.
The purpose of the initializer function in this process is to define exactly what happens in that handler, that is, what happens to the target property in response to a source property update. In essence, an initializer provides the body of the handler given to the source’s bind (that is, each binding source is an object that has a bind method, typically brought in from the WinJS.Binding.mixin or observableMixin, which is done when you call WinJS.Binding.as or WinJS.Binding.define for a data source).

In a simple binding relationship, that code might simply copy the source value to the target, or might involve a converter function. It could also consolidate multiple source properties—you can really do anything you want here. The key thing to remember is that the initializer itself will be called once and only once for each binding relationship, but the code it provides, such as a converter function, will be called every time the source property changes.

Now if you don’t specify a custom initializer within data-win-bind, WinJS will always use a default, namely WinJS.Binding.defaultBind.  It simply sets up a binding relationship that copies the source property’s value straight over to the target property, as you’d expect. In short, the following two binding declarations have identical behavior:

data-win-bind=”innerText: name”
data-win-bind=”innerText: name defaultBind”

WinJS.Binding provides a number of other built-in initializers that can come in handy:

  • oneTime Performs a one-time copy of the source property to the target property without setting up any other binding relationship. This is necessary when the source is a WinRT object, as the proxy used for marshalling doesn’t supporting observability for one-way or two-way binding.
  • setAttribute and setAttributeOneTime Similar to defaultBind and oneTime but injects a call to the target element’s setAttribute method instead of just copying the source value to a target property. This is how you bind to DOM element attributes rather than object properties.
  • addClassOneTime (WinJS 2.0 only) Like setAttributeOneTime except that it interprets the source property as a class name and thus calls the target element’s classList.add method to apply that class. This is useful when working with binding templates.

Beyond these, we enter into the realm of custom initializers. The most common and simplest case is when you need to inject a converter into the binding relationship. All this takes on your part is to pass your conversion function to WinJS.Binding.converter, which returns the appropriate initializer (that’s also marked for declarative processing). For example, in the example below the function userTypeToColor is a simple data-conversion function, so we can create an initializer within the MyInitializers namespace as follows:

WinJS.Namespace.define(“MyInitializers”, {
//…
typeColorInitializer: WinJS.Binding.converter(userTypeToColor)
});

which we use in the HTML like so:

<span id=”loginName3″
data-win-bind=”innerText: name; style.color: userType MyInitializers.typeColorInitializer”>
</span>

Doing anything more requires that you implement the initializer function directly. We’ll pick up this subject in Part 2.


A recent MSDN forum post asked a good question, one that I realized isn’t often adequately answered for developers new to the concept of data binding. It’s simply then question, “When do I use data binding at all?”

Here’s how I answered the question, and I’d enjoy hearing your thoughts on the matter.

Data binding is typically used to set up an automatic relationship between a data source and one or more UI elements. This is so you can

  1. Simplify the initialization of UI element contents from a data source (one-time binding)
  2. Have the UI elements update whenever the data source changes (one-way binding, which effectively includes one-time)
  3. Have changes in the UI element also be reflected back to the data source (two-data binding, which includes one-way)

When small bits of UI are involved, you can just as easily do all this manually, just by setting innerText/innerHTML values (or other attributes) within the appropriate event handler. However, when the UI gets more involved, e.g. you’re using collections or you’re starting to set up relationships to multiple properties of multiple elements, then having a more formalized structure to handle the data-to-UI wiring starts to make a lot of sense. This is really what data-binding is meant for (and really shines when you’re dealing with database sources and other large data sets.)

“Formalized structure” is what you often see referred to in the context of “view models” (e.g. model-view-controller (MVC), model-view-viewmodel (MVVM), and so forth). Those patterns are ones that have developed from data-binding capabilities; they encapsulate a structure wherein data (the model) is managed independently of how it’s shaped (view), how it’s presented (viewmodel), and how it’s manipulated procedurally (controller). These patterns achieve a ‘separation of concerns’ between data and UI, which is an adjunct to a similar but different separation between markup (HTML), styling (CSS), and code (JS).

[Here I inserted this note as the question was related to WinJS: Note that WinJS provides mechanisms for one-time and one-way data-binding, but not two-way; the latter, however, is not too hard to wire up on your own. I talk about all this in Chapter 4 of my book.]

The bottom line is that data binding is really a best practice, but not a requirement, especially in simple cases.


The documentation for this property has this to say: “Determines whether or not binding should automatically set the ID of an element. This property should be set to true in apps that use Windows Library for JavaScript (WinJS) binding.”

This is rather enigmatic, and the remarks section doesn’t make it much clearer when it says, “Set this property to true to avoid setting the ID of an element automatically.”

This flag was added late in the developer of Windows 8 to get around a memory leak. What was happening before is that WinJS was automatically creating an ID property for all elements involved in data binding, due to the implementation of its binding engine. However, this introduced the leak because the table in which the wwahost.exe process stores such IDs never gets cleaned up.

Generally speaking, apps didn’t depend on these IDs being created, so the WinJS team could have just made the change internally and no one would’ve noticed. However, it did constitute a breaking change so the optimizeBindingReferences flag was added such that an app that did have that dependency could turn it off.

The bottom line is that apps should set this flag to true and leave it set, thereby reducing the app’s memory footprint.