我在 Windows 8 Metro 应用程序中遇到嵌套 ListViews 的问题。我得到错误:
Exception was thrown at line 5840, column 33 in
ms-appx://microsoft.winjs.1.0/js/base.js 0x800a138f - JavaScript runtime error:
Unable to get property 'dataSource' of undefined or null reference
代码是:
<div id="color" data-win-control="WinJS.Binding.Template">
<div>color</div>
</div>
<div id="row" data-win-control="WinJS.Binding.Template">
<div>
<div>row</div>
<div
data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource : colorsDataSource.dataSource,
itemTemplate: select('#color')}">
</div>
</div>
</div>
<div id="basicListView"
data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource : Data.rowsDataSource.dataSource,
itemTemplate: select('#row')}">
</div>
有问题的行是:
data-win-options="{ itemDataSource : colorsDataSource.dataSource,
itemTemplate: select('#color')}"
问题是,在评估 data-win-options 时,colorsDataSource 不知何故无法访问 - 不知道为什么,因为数据结构 Data 是静态的,并且在 UI 甚至解析之前初始化(在 args.setPromise(WinJS .UI.processAll());)。
例如,当我尝试将行模板修改为此:
<div id="row" data-win-control="WinJS.Binding.Template">
<div>
<div>row</div>
<div data-win-bind="innerText: colorsDataSource.dataSource" ></div>
</div>
</div>
它正确输出[object Object] ...
javascript 结构 Data 如下所示:
var rows = new WinJS.Binding.List([]);
model.rows.forEach(function (row) {
rows.push({
colorsDataSource : new WinJS.Binding.List(row.rowData.colors)
});
});
Data.rowsDataSource = rows;
编辑: 嗯,我找到了原因(base.js中属性data-win-options的处理):
var options;
var optionsAttribute = element.getAttribute("data-win-options");
if (optionsAttribute) {
options = WinJS.UI.optionsParser(optionsAttribute, global, {
select: createSelect(element)
});
}
这些选项是在全局上下文中评估的,这意味着无法获取当前处理的项目(在我的情况下是行项目)......
解决方法是创建自定义渲染器(整个自定义控件)。此处部分描述了http://stephenwalther.com/archive/2012/05/23/metro-dynamically-switching-templates-with-a-winjs-listview.aspx - 请参阅 itemTemplateFunction