如果您使用的是最新版本的 jQuery Mobile,您必须知道嵌套列表仅提供部分支持。 Here's the source link.。如前所述,我们必须自己使用页面 -> 页面导航系统,所以就这样吧。
设置
我曾经为此建立了一个示例。你可以调整你的代码。
我有一个像这样的 json 对象数组:
[
{
"name": "DC Comics",
"characters": [
"All-Star Squadron",
"Birds of Prey",
...
]
},
{
"name": "Marvel Studios",
"characters": [
"Alpha Flight",
"Avengers",
"Champions",
"Defenders",
...
]
}
....
]
所以,如果您有 两页 可能会更好,其中一个用于显示主列表(即组),当单击时,另一个页面用于显示子项,即字符。
在页面加载时,我想显示如下内容:
当点击其中一个链接时,我想显示 字符数组 中存在的内容。例如,如果我选择“DC Comics”,当前上下文将是:
{
"name": "DC Comics",
"characters": [
"All-Star Squadron",
"Birds of Prey",
...
]
}
从这里,我将取出characters 属性并将其显示在新 页面的列表中。 (无论如何,这就是嵌套列表曾经做的事情)。所以,需要这样的东西:
两个页面,两个视图模型
现在要实现这一点,可能有办法。但最好的方法是使用多个 ViewModels,每个页面一个,因此将其设为 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 事件:
并将其绑定在#group-page 的pageinit 事件中:
//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 设置为 groups-page 的 DOM 元素。
同样地,你会为第二页做同样的事情,#character-page:
标记:
<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 事件:
//events pertaining to Page 1 - the groups
$(document).on({
"pageinit": function () {
//apply partial binding to character-page alone.
ko.applyBindings(groupModel, this);
}
}, "#character-page");
我们在这里使用 observables 的原因是因为每次点击某些东西时,我们都会更新 observables,这将自动更改第二页列表视图的内容。
填充第一页
这就是我的 HTML 结构的样子:
<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");
这将位于#group-page 的pageinit 事件中。
群组的点击事件,将页面更改为字符
为此,我会在第一页列表视图的a 标记上使用KO 的click 绑定:
<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>
其中 $root 是 ViewModel 级别的上下文(请参阅docs)。
哦等等!必须将getInfo 添加到第一页的模型groupModel。所以viewmodel变成了这样:
//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"
});
}
}
请注意,我现在才填充 characterModel。由于这个模型内部的属性是observables,所以每次更新这些变量时,DOM也会更新。第二页的 HTML 是:
<ul data-bind="foreach: characterInfo">
<li data-bind="text: $data"></li>
</ul>
$data 用于获取characterInfo 中的内容,如果您不知道的话。完成后,您将拥有如下内容:
下一步是刷新列表视图,但不在pageinit 中。原因是,pageinit 只被触发一次,并且由于每次点击发生时character-page 都会更新,因此您必须使用pageshow 或pagebeforshow 方法。更多信息here。现在绑定到character-page 的events 是:
//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");
上面的片段会在每次触发"#character-page" 的pagebeforeshow 事件时刷新你的样式(这是我们想要的),最后给你这个:
原来如此!希望这会有所帮助:)
而且,在我们忘记之前,
here's a demo。