jquerymobile没有使用knockoutJS渲染嵌套的listview

时间:2013-07-02 20:58:35

标签: jquery-mobile knockout.js

我正在使用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>  

当它进入嵌套列表时,那里什么也没有。我知道绑定工作正常,因为如果我删除数据角色,我会得到嵌套列表。有人可以帮忙吗?欢呼声。

1 个答案:

答案 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",
            ...
         ]
       }
       ....
]

因此,如果您有两个页面,一个用于显示主列表(即组)和单击时,可能会更好,另一个页面用于显示子项,即。,字符。

在页面加载时,我想显示如下内容:

Home page

当点击其中一个链接时,我想显示 characters array 中存在的内容。例如,如果我选择“DC Comics”,则当前上下文将是:

{
   "name": "DC Comics",
   "characters": [
       "All-Star Squadron",
       "Birds of Prey",
             ...
    ]
}

从这里开始,我会取出characters媒体资源,并在页面的列表中显示。 (无论如何,这是嵌套列表的用途)。所以,需要这样的东西:

characters

两页,两个ViewModels

现在要做到这一点,可能有办法。但最好的方法是使用多个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> 内的内容。完成后,你会有这样的事情:

unrefreshed listview

下一步是刷新列表视图,但不是$data。原因是characterInfo只被触发一次,而且每次点击发生时pageinit都会更新,您就可以使用pageinitcharacter-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"); 事件时,上述剪辑都会刷新您的样式(这就是我们想要的)并最终为您提供:

Final output

就是这样!希望这有助于:)

而且,在我们忘记之前,

here's a demo