Sourav Basu
Sourav Basu

Reputation: 11

Data Bind failing for Custom HtmlControl inside ItemTemplate of ListView

I have an ItemTemplate which is set on a ListView:

<div class="commentTileTemplate" data-win-control="WinJS.Binding.Template">
    <div class="commentTileControl" data-win-control="WinJS.UI.HtmlControl" data-win-options="{uri: '/htmlControls/commentTile/commentTile.html'}"></div>
</div>

The data bindings which are inside the HtmlControl, fails to bind the first time the ListView is shown, on successive runs, it works fine.

If I remove the template from the ListView, then the raw data shows up as expected, only upon adding the HtmlControl it fails the first.

Any idea what might be wrong?

Upvotes: 1

Views: 1083

Answers (1)

Dominic Hopton
Dominic Hopton

Reputation: 7292

This is because the first time you are loading the control, the page is loaded asynchronously through an XHR (WinJS.xhr) from the package. This means that when the first WinJS.Binding.process() happens in the WinJS.Binding.Template.render function, the actual content isn't loaded. (e.g. it's query selector doesn't see any data-win-bind attributes.

The second time, because the fragment you are loading is already in the fragment cache, it actually renders into the DOM synchronously and the WinJS.Binding.Template.render's WinJS.Binding.processAll sees those data-win-bind attributes.

This leaves you with some options:

  1. preload the fragment with WinJS.UI.Fragments.cache() as soon as your app starts, and don't set the data on the list view until that fragment completes
  2. Only instantiate the HtmlControl when your item has been rendered, and then programmatically instantiate the HtmlControl, and WinJS.Binding.process[All]() the loaded template when it loads [1]
  3. Actually make the template your content, and then load the fragment, process the control. This is easier than it looks, but may take some time to think about. In short: Load Fragment, querySelector on the fragment for the element that you have data-win-control on, WinJS.UI.process() it, and return the template instance back to the caller and use that as the itemTemplate on your list view

[1] The HtmlControl Constructor takes a 3rd parameter, which is a callback called when the fragment is loaded.

Upvotes: 2

Related Questions