Search code examples
javascriptmicrosoft-metrowinjs

data-win-bind issues: converter only runs once and unable to bind id of element


I have the following html that is bound to an object containing id and status. I want to translate status values into a specific color (hence the converter function convertStatus). I can see the converter work on the first binding, but if I change status in the binding list I do not see any UI update nor do I see convertStatus being subsequently called. My other issue is trying to bind the id property of the first span does not seem to work as expected (perhaps it is not possible to set this value via binding...)

HTML:

<span data-win-bind="id: id">person</span>
<span data-win-bind="textContent: status converter.convertStatus"></span>

Javascript (I have tried using to modify the status value):

// persons === WinJS.Binding.List
// updateStatus is a function that is called as a result of status changing in the system

function updateStatus(data) {
    persons.forEach(function(value, index, array) {
        if(value.id === data.id) {
            value.status = data.status;
            persons.notifyMutated(index);
        }
    }, this);
}

I have seen notifyMutated(index) work for values that are not using a converter.

Updating with github project

Public repo for sample (not-working) - this is a really basic app that has a listview with a set of default data and a function that is executed when the item is clicked. The function attempts to randomize one of the bound fields of the item and call notifyMutated(...) on the list to trigger a visual updated. Even with defining the WinJS.Binding.List({ binding: true }); I do not see updates unless I force it via notifyReload(), which produces a reload-flicker on the listview element.


Solution

  • To answer your two questions:

    1) Why can't I set id through binding?

    This is deliberately prevented. The WinJS binding system uses the ID to track the element that it's binding to (to avoid leaking DOM elements through dangling bindings). As such, it has to be able to control the id for bound templates.

    2) Why isn't the converter firing more than once?

    The Binding.List will tell the listview about changes in the contents of the list (items added, removed, or moved around) but it's the responsibility of the individual items to notify the listview about changes in their contents.

    You need to have a data object that's bindable. There are a couple of options:

    • Call WinJS.Binding.as on the elements as you add them to the collection
    • Turn on binding mode on the Binding.List

    The latter is probably easier. Basically, when you create your Binding.List, do this:

    var list = new WinJS.Binding.List({binding: true});
    

    That way the List will call binding.as on everything in the list, and things should start updating.