Manuel Schweigert
Manuel Schweigert

Reputation: 4974

WinJS Navigation Template + ListView

I have started out with the navigation template and tried to put a ListView WinControl into a page (not home.html). Inserting HTML works correctly, the Javascript also executes correctly.

When trying to bind a listview using data-win-options however, I encounter the problem that the Namespace I define in the ready handler in JS doesn't exist yet, so the app throws an exception.

If I define the Namespace before the ready event, there is no exception, but the update to the "public" variable I perfom in the ready handler is not reflected in the ListView, only when I navigate back and into the page again is the ListView filled correctly with data.

The only way I found to make a ListView work for now is to directly update

document.getElementById('myListView').winControl.itemDataSource

Which really isn't the way I want to go. I'd like the binding to be in HTML.

So to sum it up, what is the correct way to bind a ListView in the Navigation Template? Or am I the only one having this problem?

Upvotes: 1

Views: 1202

Answers (1)

Dominic Hopton
Dominic Hopton

Reputation: 7292

There are a couple moving parts here.

First, because the variable you have your data source is not "Observable" -- it won't notify anyone that it's changed. Thats not something that JavaScript can intrinsically do.

Second, you've passed it via the data-win-options bucket -- which just captures the value, and makes no effort to observe it.

There are a few ways to solve this:

a) Leverage the way you've found, but make your variable observable, and transfer the value when it changes by adding a change handler. This isn't declarative as you desire but isn't bad.

var yourVariable = WinJS.Binding.as({ dataSource: null });
yourVariable.bind("dataSource", function(oldVal, newVal) {
    document.getElementById("yourListView").winControl.itemDataSource = newVal;
});

yourVariable.dataSource = getMyDataYo();

b) Set up declarative binding in the HTML, and call WinJS.Binding.processAll() with a data context.

HTML:

<div data-win-control="WinJS.UI.ListView"
     data-win-options="{ itemTemplate:... }"
     data-win-bind="winControl.itemDataSource: dataSourceProperty"
</div>

JS: In your ready handler:

var dataContext = WinJS.Binding.as({ dataSourceProperty: dataSourceInstance });
WinJS.Binding.processAll(element, dataContext);

If you save off the dataContext instance, when you set the dataSourceProperty in the future with a new datasource, the listview will reload, and re-layout.

Upvotes: 2

Related Questions