我正在使用knockoutjs绑定一个嵌套的listview,并使用像这样的JQuery mobile来设置样式
<ul id="machine-list" data-bind="foreach: machineList" data-role="listview">
<li><span data-bind="text:location"></span>
<ul data-bind="foreach: machines" data-role="listview">
<li><span data-bind="text:machine"></span></li>
</ul>
</li>
</ul>
当它进入嵌套列表时,那里什么也没有。我知道绑定工作正常,因为如果我删除数据角色,我会得到嵌套列表。有人可以帮忙吗?欢呼声。
答案 0 :(得分:1)
如果您使用的是最新版本的jQuery Mobile,则必须知道嵌套列表只有部分支持。 Here's the source link.。如上所述,我们必须使用页面 - &gt;我们自己的页面导航系统,所以这里。
我在某个时候为此建立了一个例子。你可以调整你的代码。
我有一个 json
对象数组,如下所示:
[
{
"name": "DC Comics",
"characters": [
"All-Star Squadron",
"Birds of Prey",
...
]
},
{
"name": "Marvel Studios",
"characters": [
"Alpha Flight",
"Avengers",
"Champions",
"Defenders",
...
]
}
....
]
因此,如果您有两个页面,一个用于显示主列表(即组)和单击时,可能会更好,另一个页面用于显示子项,即。,字符。
在页面加载时,我想显示如下内容:
当点击其中一个链接时,我想显示 characters array 中存在的内容。例如,如果我选择“DC Comics”,则当前上下文将是:
{
"name": "DC Comics",
"characters": [
"All-Star Squadron",
"Birds of Prey",
...
]
}
从这里开始,我会取出characters
媒体资源,并在新页面的列表中显示。 (无论如何,这是嵌套列表的用途)。所以,需要这样的东西:
现在要做到这一点,可能有办法。但最好的方法是使用多个ViewModel ,每个页面一个,因此将其设置为 2 并在初始化该特定页面时绑定它。所以对于特定的页面,
加价:
<div data-role="page" id="groups-page"></div>
查看型号:
我们有一个单独的ViewModel
:
//view model for the parent page.
var groupModel = {
//data array
groupInfo: [
{
"name": "DC Comics",
"characters": [
"All-Star Squadron",
"Birds of Prey",
...
]
},
{
"name": "Marvel Studios",
"characters": [
"Alpha Flight",
"Avengers",
"Champions",
"Defenders",
...
]
}
....
]
}
pageinit
事件:
并在pageinit
的{{1}}事件中绑定它:
#group-page
请注意,//events pertaining to Page 1 - the groups
$(document).on({
"pageinit": function () {
//apply partial binding to groups-page alone. Reason we're doing this is because only this page will be available onload
ko.applyBindings(groupModel, this);
}
}, "#groups-page");
(applyBindings
)中的第二个对象表示将this
设置为id
的DOM元素。
同样,你会对第二页groups-page
:
加价:
#character-page
ViewModel:
<div data-role="page" id="character-page"></div>
//view model for the character page - basically an empty view model to be filled with data when a link is clicked.
var characterModel = {
name: ko.observable(),
characterInfo: ko.observableArray()
}
事件:
pageinit
我们在这里使用observable的原因是因为每次点击某些内容时,我们都会更新observable,它会自动更改第二页listview的内容。
这就是我的HTML结构的样子:
//events pertaining to Page 1 - the groups
$(document).on({
"pageinit": function () {
//apply partial binding to character-page alone.
ko.applyBindings(groupModel, this);
}
}, "#character-page");
在<ul data-bind="foreach: groupInfo">
<li>
<a href="#">
<span data-bind="text: name"></span>
<span data-bind="text: characters.length" class="ui-li-count"></span>
</a>
</li>
</ul>
仅绑定到第一页后,我会在页面中对这些列表视图进行刷新:
applyBindings()
这将取决于 //apply partial binding to groups-page alone. Reason we're doing this is because only this page will be available onload
ko.applyBindings(groupModel, this);
//refresh the listview
$("ul", this).attr("data-role", "listview").listview().listview("refresh");
的{{1}}事件。
为此,我会在第一页的listview的pageinit
标记上使用KO的#group-page
绑定:
click
其中$ root是ViewModel级别的上下文(请参阅docs)。
哦等等! a
必须添加到第一页的模型<a href="#" data-bind="click: $root.getInfo">
<span data-bind="text: name"></span>
<span data-bind="text: characters.length" class="ui-li-count"></span>
</a>
。所以viewmodel改为:
getInfo
请注意,我现在只填充groupModel
。由于此模型中的属性为//view model for the parent page.
var groupModel = {
//data array
groupInfo: [
//groups
],
//click event to be fired when an anchor tag is clicked
getInfo: function (data, e) {
//here "data" variable gives the clicked elements' corresponding array and "e" gives the event object
//prevents defaultbehaviour of anchor tag
e.preventDefault();
//setting up the character array in View model of page 2
characterModel.characterInfo(data.characters);
//setting up name variable of ViewModel in page 2
characterModel.name(data.name);
//change the page
$.mobile.changePage("#character-page", {
transition: "slide"
});
}
}
,因此每次更新这些变量时,DOM也会更新。第二页的HTML是:
characterModel
如果您不知道, observables
用于获取<ul data-bind="foreach: characterInfo">
<li data-bind="text: $data"></li>
</ul>
内的内容。完成后,你会有这样的事情:
下一步是刷新列表视图,但不是$data
。原因是characterInfo
只被触发一次,而且每次点击发生时pageinit
都会更新,您就可以使用pageinit
或character-page
方法。更多信息here。现在绑定到pageshow
的{{1}}是:
pagebeforshow
每次触发events
character-page
//events pertaining to Page 2 - the characters
$(document).on({
"pageinit": function () {
ko.applyBindings(characterModel, this);
},
"pagebeforeshow": function () {
//refresh listview before page is shown
$("ul", this).attr("data-role", "listview").listview().listview("refresh");
}
}, "#character-page");
事件时,上述剪辑都会刷新您的样式(这就是我们想要的)并最终为您提供:
就是这样!希望这有助于:)