1

I'm binding a nested listview with knockoutjs and styling it with JQuery mobile like this

        <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>  

When it goes to the nested list there's nothing there. I know the binding is working because if I remove the data-role I get the nested list. Can anyone help? Cheers.

4

1 回答 1

1

如果您使用的是最新版本的 jQuery Mobile,您必须知道嵌套列表只有部分支持。 这是源链接。. 如前所述,我们必须自己使用页面 -> 页面导航系统,所以就这样吧。

设置

我在某个时候为此建立了一个示例。你可以调整你的代码。我有一个像这样的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属性并将其显示在页面的列表中。(无论如何,这就是嵌套列表曾经做的事情)。因此,需要这样的东西:

人物

两个页面,两个 ViewModel

现在要实现这一点,可能有办法。但是最好的方法是使用多个 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事件:pageinit并在以下事件中 绑定它#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的 DOM 元素。idgroups-page

同样,你会为第二页做同样的事情,#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");

这将pageinit#group-page.

组的点击事件,将页面更改为字符

为此,我会在第一页的列表视图click的标签上使用 KO 的绑定: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>

其中 $root 是 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"
        });
    }
}

请注意,我现在填充的是characterModel唯一的。由于该模型内部的属性是observables,因此每次更新这些变量时,DOM 也会更新。第二页的 HTML 是:

<ul data-bind="foreach: characterInfo">
    <li data-bind="text: $data"></li>
 </ul>

$data用于获取里面的东西characterInfo,如果你不知道的话。完成后,您将拥有以下内容:

未刷新的列表视图

下一步是刷新列表视图,但不是在pageinit. 原因是,pageinit仅触发一次,并且character-page每次点击都会更新,因此您必须使用pageshoworpagebeforshow方法。更多信息在这里。现在的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");  

pagebeforeshow每次触发事件时,上面的片段都会刷新你的样式"#character-page"(这是我们想要的),最后给你这个:

最终输出

就是这样了!希望这有帮助:)

而且,在我们忘记之前,

这是一个演示

于 2013-07-03T04:36:44.450 回答