问题
For some reason, my template is not getting used in the binding of data. I'm using Visual Studio's "Navigation App" project type for Windows 8 app. When I run it, each item just gets filled with the full json string. Similar to binding without using any templates at all.
home.js:
var dataList = new WinJS.Binding.List();
var publicMembers = { itemList: dataList };
WinJS.Namespace.define("VideosData", publicMembers);
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/home/home.html", {
ready: function (element, options) {
dataList.push({title: 'title 1'});
dataList.push({title: 'title 1'});
}
});
})();
home.html:
<section aria-label="Main content" role="main">
<div id="videosWin8Tmpl" data-win-control="WinJS.Binding.Template" style="display:none">
<div><span class="detail" data-win-bind="innerText: title"></span></div>
</div>
<div id="videosListView" data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: VideosData.itemList.dataSource, itemTemplate: videosWin8Tmpl, layout: { type: WinJS.UI.GridLayout } }"></div>
</section>
What's getting outputted:
{"title":"title 1"}
{"title":"title 2"}
Why isn't the template getting used in the binding? Thanks.
回答1:
The reason for the behavior you're seeing is subtle. I'll explain below, but the short answer is:
Don't look stuff up by id in a page control. Use classes and the select syntax instead.
The following will work in your page control:
<section aria-label="Main content" role="main">
<div class="videosWin8Tmpl"
data-win-control="WinJS.Binding.Template" style="display:none">
<div><span class="detail" data-win-bind="innerText: title"></span></div>
</div>
<div id="videosListView" data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource: VideosData.itemList.dataSource,
itemTemplate: select('.videosWin8Tmpl'),
layout: { type: WinJS.UI.GridLayout } }">
</div>
</section>
So, what's going on?
When you do itemTemplate: videosWin8Tmpl
in your options record, at processing time WinJS will look for a global variable named videosWin8Tmpl, and that'll be passed to the control as the template object. This normally works because the browser automatically creates global variables for each element with an ID.
However, when loading a page control, at the time WinJS.UI.processAll is called, the DOM for the page hasn't yet been added to the global document. As such, the browser hasn't yet created the global variable, and thus it doesn't find the template.
the select(...) expression doesn't rely on global variables, instead looking upwards from the element the options record is specified on, so it can find the template correctly.
回答2:
Got it - I moved the template snippet over to default.html just above <div id="contenthost">...</div>
and the binding could find it then. Not sure why it had to be in default.html
and not in home.html
.
来源:https://stackoverflow.com/questions/13479847/binding-listview-on-a-page-control-using-template-in-windows-8